Android中POST curl请求转Retrofit请求返回400错误排查
问题根因
- 核心用法错误:
@Body参数直接传入提前序列化好的JSON字符串不符合Retrofit的Gson转换器逻辑。配置GsonConverterFactory后,Retrofit会自动对@Body传入的对象执行JSON序列化,你提前将实体类转为String再传入,Gson会把这个字符串当成普通文本值做二次序列化:最终请求体被额外包裹一层双引号,内部所有双引号被转义,根本不是接口要求的合法JSON结构,服务端解析失败直接返回400。 - 接口版本不匹配:日志显示实际请求的是v12.0版本的Graph接口,你参考的curl示例用的是v13.0版本,不同版本的参数校验规则存在差异,也可能触发请求错误。
- 冗余头配置:手动传入
Content-Type请求头属于多余操作,Gson转换器会自动为JSON请求添加正确的Content-Type: application/json头,手动重复声明可能导致头信息异常。
修复步骤
- 修改APIService定义,移除Content-Type手动传参,
@Body直接使用实体类类型,不要用String:
public interface APIService { @POST("{phoneNoId}/messages") Call<MsgResponse> SendMsg(@Path("phoneNoId") String phoneNoId, @Header("Authorization") String authorization, @Body MsgRequest msgObj ); }
- 发起请求时移除提前序列化JSON的逻辑,直接传入实体类对象,由Retrofit自动完成序列化:
// 删除这行提前序列化的代码:String jsonBody=gson.toJson(msgObj); APIService apiService=RetroInstance.getRetrofitClient().create(APIService.class); Call<MsgResponse> call=apiService.SendMsg("100798385993185", "Bearer 5iWIZBiI5vogoNZBKbBJ0oZAibvZBG---token--xIcDPoW", msgObj ); call.enqueue(new Callback<MsgResponse>() { @Override public void onResponse(Call<MsgResponse> call, Response<MsgResponse> response) { if (!response.isSuccessful()) { try { // 打印服务端返回的具体错误信息,方便后续定位问题 Log.e(TAG, "请求错误详情: " + response.errorBody().string()); } catch (IOException e) { e.printStackTrace(); } return; } // 正常响应处理逻辑 Log.d(TAG, "onResponse: "+response.body()); } @Override public void onFailure(Call<MsgResponse> call, Throwable t) { Log.d(TAG, "onFailure: "+t.getMessage()); } });
- 检查Retrofit初始化配置的baseUrl,将接口版本修正为v13.0,确保路径格式正确:
// 正确的baseUrl配置,注意末尾必须带斜杠 public static final String BASE_URL = "https://graph.facebook.com/v13.0/"; Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build();
报错参考截图:
内容的提问来源于stack exchange,提问作者Prasath S
相关产品推荐
相关产品推荐

