Retrofit请求返回200但ResponseBody为null,求问题排查
我帮你梳理了代码里的问题,核心出在请求参数的提交格式不匹配上,导致服务器虽然返回200状态码,但Retrofit无法正确解析响应体,最终出现response.body() == null的情况。下面具体分析问题和解决方案:
问题定位
从你提供的参数体和ApiInterface定义来看,服务器期望接收的是JSON格式的请求体,但你的代码用了@FormUrlEncoded和@Field注解——这会让Retrofit以application/x-www-form-urlencoded的表单格式发送请求,和服务器预期的application/json格式完全不匹配。
这种情况下,服务器可能无法正确解析你传递的参数,虽然返回了200状态码,但实际返回的响应内容可能不符合TransferCenterStoreResponse的结构,或者Retrofit在解析时直接失败,导致response.body()为null。
解决方案
1. 创建请求体实体类
先定义一个和服务器参数结构对应的实体类,用来封装请求参数:
public class TransferRequest { @SerializedName("ProcName") private String procName; @SerializedName("Parameters") private List<TransferCenterStoreParameters> parameters; // 构造方法 public TransferRequest(String procName, List<TransferCenterStoreParameters> parameters) { this.procName = procName; this.parameters = parameters; } // 按需添加getter、setter方法 }
2. 修改ApiInterface注解
去掉@FormUrlEncoded,改用@Body注解传递JSON请求体:
@POST("GetDispatchList") Call<TransferCenterStoreResponse> TRANSFER_CENTER_STORE_RESPONSE_CALL( @Header("Authorization") String authHeader, @Body TransferRequest requestBody );
3. 调整调用代码
创建TransferRequest对象并传入接口方法:
private void getTransferBtwCenterAndOffice(){ showProgressDialog(getString(R.string.wait_message)); ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); String userName = tinyDb.getString(Constant.userName); String passWord = tinyDb.getString(Constant.token); List<TransferCenterStoreParameters> parameters = new ArrayList<>(); parameters.add(new TransferCenterStoreParameters("StoreCode","B201")); // 创建请求体对象 TransferRequest request = new TransferRequest("BR_SP_BRN_GET_STORE_ACTIVE_SHIPMENTS", parameters); String base = userName + ":" + passWord; String authHeader = "Basic "+ Base64.encodeToString(base.getBytes(),Base64.NO_WRAP); Call<TransferCenterStoreResponse> call = apiService.TRANSFER_CENTER_STORE_RESPONSE_CALL(authHeader, request); call.enqueue(new Callback<TransferCenterStoreResponse>() { @Override public void onResponse(Call<TransferCenterStoreResponse> call, retrofit2.Response<TransferCenterStoreResponse> response) { hideProgressDialog(); Log.d(CLASS_NAME, "onResponse: "+response); // 补充:先判断请求是否成功 if(response.isSuccessful()){ TransferCenterStoreResponse body = response.body(); if(body != null){ if(body.getTransferBtwCenterStoreResult().getResultCode().equals("200")){ List<TransferCenterStore> mList = body.getTransferCenterStoresList(); // 处理数据逻辑 } else{ getAlert(body.getTransferBtwCenterStoreResult().getErrorMessage()); } } else { Log.d(CLASS_NAME, "Response body is null, check server response format"); } } else { // 打印错误响应内容,方便排查 try { String errorContent = response.errorBody().string(); Log.e(CLASS_NAME, "Error response: " + errorContent); } catch (IOException e) { e.printStackTrace(); } } } @Override public void onFailure(Call<TransferCenterStoreResponse> call, Throwable t) { hideProgressDialog(); Log.e(CLASS_NAME, t.toString()); } }); }
4. 确认Retrofit配置
确保你的ApiClient.getClient()中配置了Gson转换器,这样Retrofit才能正确解析JSON响应:
Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) // 替换成你的实际baseUrl .addConverterFactory(GsonConverterFactory.create()) .client(new OkHttpClient.Builder().build()) .build();
额外排查建议
如果修改后还是出现response.body() == null,可以在onResponse中打印response.errorBody()的内容——服务器可能返回了错误信息在里面,能帮你进一步定位问题。
内容的提问来源于stack exchange,提问作者cartoonworld

