You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将MOT历史API的CURL转为Android Java代码解决403认证错误

问题:Android调用MOT历史API返回403未授权错误

我尝试实现MOT历史API,其提供的CURL示例通过在线工具测试时,使用给定的API密钥可成功运行。但在Android中用HttpPost实现时,请求返回403状态码,提示“未授权——请求头中的x-api-key缺失或无效”,但密钥本身是有效的。

我的代码如下:

//Tried with full URL and by adding the registration as a header.
//HttpPost httpPost = new HttpPost("https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?registration=" + reg_selected);
HttpPost httpPost = new HttpPost("https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests");

httpPost.addHeader("Content-Type", "application/json");
httpPost.addHeader("Accept", "application/json+v6");
httpPost.addHeader("x-api-key", "abcdefgh123456");
httpPost.addHeader("registration", reg_selected);

StringEntity entity = new StringEntity(jsonObj.toString(), HTTP.UTF_8);
httpPost.setEntity(entity);
HttpClient client = new DefaultHttpClient();

try {
     HttpResponse response = client.execute(httpPost);

     if (response.getStatusLine().getStatusCode() == 200) {

          InputStream inputStream = response.getEntity().getContent();
          bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
          String readLine = bufferedReader.readLine();

          String jsonStr = readLine;
          JSONObject myJsonObj = new JSONObject(jsonStr);

          
     }else if (response.getStatusLine().getStatusCode() == 400){
            //Bad Request  Invalid data in the request. Check your URL and parameters
            error_text = "Bad Request";
     }else if (response.getStatusLine().getStatusCode() == 403){
           //Unauthorised – The x-api-key is missing or invalid in the header
           error_text = "Authentication error"; //<<<< FAILS HERE 403
     }
} catch (Exception e) {
     // 异常处理
}

请问如何正确将该CURL转换为Android Java代码,避免服务器返回403错误?


解决方案

核心问题分析

  1. 请求方式错误:该MOT历史API的车辆查询接口实际为GET请求,而非你使用的POST请求,服务器会拒绝不符合要求的请求方式,导致403。
  2. 参数传递错误:registration(车牌)应作为URL查询参数传递,而非放在请求头中。
  3. 使用废弃API:DefaultHttpClient在Android 6.0(API 23)后已被废弃,存在兼容性和安全问题,建议改用HttpURLConnection或OkHttp。

修正后的代码示例(使用OkHttp,推荐)

首先在build.gradle中添加OkHttp依赖:

implementation 'com.squareup.okhttp3:okhttp:4.12.0'

然后编写请求代码:

String apiKey = "abcdefgh123456";
String registration = reg_selected;
// 对车牌参数进行URL编码,避免特殊字符导致请求异常
String encodedReg = URLEncoder.encode(registration, "UTF-8");
String url = "https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?registration=" + encodedReg;

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
        .url(url)
        .addHeader("Accept", "application/json+v6")
        .addHeader("x-api-key", apiKey)
        .get() // 明确指定GET请求
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {
        // 请求失败处理
        e.printStackTrace();
    }

    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
        if (response.isSuccessful()) {
            // 解析响应
            String jsonStr = response.body().string();
            try {
                JSONObject myJsonObj = new JSONObject(jsonStr);
                // 处理返回数据
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            switch (response.code()) {
                case 400:
                    error_text = "Bad Request";
                    break;
                case 403:
                    error_text = "Authentication error";
                    break;
                default:
                    error_text = "Request failed with code: " + response.code();
            }
        }
    }
});

使用HttpURLConnection的替代方案

如果你不想引入第三方库,也可以用原生的HttpURLConnection:

String apiKey = "abcdefgh123456";
String registration = reg_selected;
String encodedReg = URLEncoder.encode(registration, "UTF-8");
String urlStr = "https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?registration=" + encodedReg;

// 网络请求必须在子线程执行
new Thread(() -> {
    HttpURLConnection connection = null;
    BufferedReader reader = null;
    try {
        URL url = new URL(urlStr);
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Accept", "application/json+v6");
        connection.setRequestProperty("x-api-key", apiKey);

        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String jsonStr = sb.toString();
            JSONObject myJsonObj = new JSONObject(jsonStr);
            // 处理返回数据
        } else {
            switch (responseCode) {
                case HttpURLConnection.HTTP_BAD_REQUEST:
                    error_text = "Bad Request";
                    break;
                case HttpURLConnection.HTTP_FORBIDDEN:
                    error_text = "Authentication error";
                    break;
                default:
                    error_text = "Request failed with code: " + responseCode;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}).start();

注意事项

  • 所有网络请求必须在子线程中执行,避免触发Android主线程网络操作限制。
  • 务必对registration参数进行URL编码,防止特殊字符(如空格、符号)导致请求格式错误。
  • 确认API密钥与CURL测试时完全一致,无额外空格或特殊字符。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:24:04