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
相关产品推荐
相关产品推荐

