Retrofit调用POST接口返回200但服务端判定请求为空问题排查
Retrofit POST请求服务端读取不到内容的调整方案
核心问题修正
- RequestBody构建参数顺序错误:Retrofit 2 配套的OkHttp 3.0及以上版本中,
RequestBody.create()的Java方法签名为create(MediaType contentType, String content),你代码中写的RequestBody.create(json.toString(), MediaType.parse("application/json;charset=UTF-8"))完全颠倒了参数顺序,导致最终构建的请求体并非你拼接的JSON内容,服务端自然无法解析到有效数据。
正确构建写法:// 修正变量名不一致问题:你声明的是jsonObject,之前错误引用了不存在的json变量 RequestBody body = RequestBody.create( MediaType.parse("application/json;charset=UTF-8"), jsonObject.toString() ); - 接口定义冗余:项目已经集成了
GsonConverterFactory,无需手动构建RequestBody,直接传入业务对象/JSONObject即可,Gson会自动完成序列化和请求头设置,减少手动处理的出错概率。调整后的接口定义:
调用时直接传入拼接好的@Headers({"org-id: vuk"}) @POST("/dmp/user/loginwithotp") Call<ResponseAPI> signInWithOTP(@Body JSONObject requestJson);jsonObject即可,不需要手动转换为RequestBody。
拦截器逻辑排查修正
- 检查
CacheInterceptor实现:POST类写操作不应该被本地缓存拦截,如果你的网络拦截器给POST请求添加了缓存规则,会导致请求直接命中本地缓存、根本不向服务端发送真实请求体,自然会出现服务端读不到内容的问题。需要在缓存拦截器中为POST请求强制绕过缓存,不做任何缓存读写处理。 - 开启日志拦截器的全量请求日志:将
HttpLoggingInterceptor的日志级别设置为Level.BODY,可以在控制台直接看到实际发出的请求头、请求体内容,直观验证是否真的把JSON数据发送出去了,避免排查方向错误。设置方式:HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
响应处理逻辑修正
- 当前代码的日志分支逻辑错误:
response.isSuccessful()仅在HTTP状态码为200-299时返回true,你把响应体日志打印写在了if(!response.isSuccessful())分支里,意味着只有非2xx状态码的请求才会打日志,完全覆盖不了“200状态码但业务失败”的场景。调整后的响应处理逻辑:@Override public void onResponse(Call<ResponseAPI> call, retrofit2.Response<ResponseAPI> response) { // 不管状态码是多少,先打印基础信息和响应体,方便排查 Log.d("TAG", "HTTP状态码: " + response.code()); Log.d("TAG", "响应内容: " + new Gson().toJson(response.body())); // 再根据业务字段做后续判断 }
额外排查项
- 确认
baseUrl格式正确,末尾必须携带/,接口路径不要以/开头,避免路径拼接异常导致请求到错误的服务节点。 - 对比Postman的请求头列表,确认代码中的请求头没有被其他拦截器覆盖,尤其是
Content-Type: application/json头,一旦被覆盖为其他类型,服务端会无法解析JSON内容,抛出“请求内容为空”的错误。
内容的提问来源于stack exchange,提问作者Disha Singh
相关产品推荐
相关产品推荐

