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

OkHttpClient Java请求异常:Tomcat返回无效请求,求调试方案

调试OkHttpClient请求返回"Invalid request."问题的技巧与解决方法

问题场景

使用OkHttpClient发起POST请求,代码逻辑看似正常,但Tomcat服务器始终返回“Invalid request.”错误,需排查问题并给出解决方法。

相关代码

public void postAsync(String payload, String action, Callback callback) throws JSONException {
    //Gson gJSON = new Gson();
    // Convert payload to a JSON object
    JSONObject jsonObject = new JSONObject();

    // Add the action property to the JSON object
    jsonObject.put("action", action);
    jsonObject.put("payload",payload);

    // Convert the modified JSON object back to a string
    String payloadWithAction = jsonObject.toString();

    RequestBody body = RequestBody.create(payloadWithAction, MediaType.parse("application/json"));

    Request request = new Request.Builder()
            .header("Content-Type", "application/json")
            .url("https://moveroute.org/php/run-register-api.php")
            .post(body)
            .build();
    System.out.println(request.isHttps());
    client.newCall(request).enqueue(callback);

}

try {
    makeLogin.postAsync(payload, "login", new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            // Handle failure
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {

            if (response.isSuccessful()) {

                String jsonResponse = response.body().string();
                Gson gJson = new Gson();
                CRUD.Response responseJSON = gJson.fromJson(jsonResponse, CRUD.Response.class);
                System.out.println(responseJSON.getMessage().toString());
                if (responseJSON.getStatus()){
                    Intent goToMainView = new Intent(MainActivity.this, MainView.class);
                    startActivity(goToMainView);
                    finish();
                }

            } else {
                // Handle unsuccessful response
            }
        }
    });
} catch (JSONException e) {
    throw new RuntimeException(e);
}

调试技巧与解决方法

1. 抓包验证实际请求

  • 使用Charles、Fiddler等工具抓取真实请求,对比请求头、请求体与接口文档要求是否一致:
    • 确认Content-Type是否确实为application/json,排查是否被拦截器篡改
    • 检查请求体JSON格式是否合法,比如payload本身若为JSON字符串,直接放入会导致嵌套结构错误(变成字符串而非JSON对象)
    • 验证请求URL是否正确,是否存在重定向、路径拼写错误

2. 校验请求体合法性

  • 在代码中临时添加日志,输出最终生成的请求体字符串,用JSON校验工具验证格式:
    System.out.println("Final Request Body: " + payloadWithAction);
    
  • 如果payload本身是JSON字符串,需将其转为JSON对象再嵌套,避免格式损坏:
    // 替换原put语句
    jsonObject.put("payload", new JSONObject(payload));
    

3. 优化请求头设置

  • 依赖RequestBody的MediaType自动设置Content-Type,避免手动设置导致的冲突:
    RequestBody body = RequestBody.create(payloadWithAction, MediaType.get("application/json; charset=utf-8"));
    // 移除手动添加的Content-Type头
    Request request = new Request.Builder()
            .url("https://moveroute.org/php/run-register-api.php")
            .post(body)
            .build();
    
  • 检查服务器是否要求其他必选请求头(如User-Agent),缺失可能触发拦截

4. 模拟请求对比测试

  • 用Postman、curl复制抓包得到的请求参数直接发送:
    • 若同样返回错误,说明问题在服务器端或请求参数不符合接口要求
    • 若模拟请求正常,说明代码中存在隐蔽问题(如字符编码、请求头顺序、特殊字符转义)

5. 排查OkHttpClient配置

  • 检查是否添加了拦截器,是否存在篡改请求的逻辑
  • 临时关闭HTTPS证书校验(仅用于测试,生产环境禁用),排查证书信任问题:
    OkHttpClient client = new OkHttpClient.Builder()
            .sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager())
            .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
            .build();
    
    注:SSLSocketClient为自定义忽略证书校验的工具类

6. 完善错误响应处理

  • 在onResponse的else分支中输出完整错误信息,获取服务器返回的详细原因:
    } else {
        System.out.println("Response Code: " + response.code());
        System.out.println("Error Details: " + response.body().string());
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:24:50