使用Retrofit和OkHttp发起POST请求返回400错误求助
遇到400 Bad Request确实挺闹心的,结合你贴出的代码,咱们一步步梳理可能的原因:
请求体序列化不匹配
你用@Body EvreyId evreyId传递请求体,首先得确认EvreyId类的字段序列化是否和后端接口要求一致:- 检查字段是否加了
@SerializedName注解?如果后端参数名是下划线风格(比如user_id),而你的类字段是驼峰式(userId),没加注解的话Gson会按驼峰序列化,后端识别不了就会返回400。 - 确认
EvreyId实例的必填字段都已赋值,有没有遗漏后端要求的必填参数,或者传了null给非空字段。
- 检查字段是否加了
Authorization头格式错误
后端通常要求Authorization头是Bearer + 空格 + Token的格式(比如Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...)。如果你只传了Token字符串没加Bearer前缀,或者格式不符合后端要求,就会触发验证失败,返回400。Content-Type与转换器不兼容
你在接口上标注了@Headers("Content-Type: application/json"),要确保Retrofit配置了正确的JSON转换器(比如GsonConverterFactory)。如果用了错误的转换器(比如ScalarsConverterFactory),请求体无法被序列化为JSON格式,后端解析失败就会返回400。接口路径拼接错误
检查@POST("message/save")的相对路径和OkHttpClient的baseUrl拼接后是否正确:- 如果
baseUrl是http://your-domain.com/api(末尾没加斜杠),拼接后会变成http://your-domain.com/apimessage/save,这显然是无效路径,会导致请求错误。正确的baseUrl应该以斜杠结尾,比如http://your-domain.com/api/。
- 如果
后端参数校验不通过
有些后端接口会对参数做格式校验(比如日期格式、数字范围、字符串长度),或者要求额外的请求头。你可以用Postman/curl直接模拟相同请求,如果Postman能成功,对比自己代码发送的请求头、请求体,找出差异点。
调试建议:打印完整请求日志
添加OkHttp的日志拦截器,能直观看到实际发送的请求细节,快速定位问题:
// 添加依赖:implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0' HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build(); // 把这个client传给Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build();
之后在Logcat里就能看到完整的请求头、请求体、响应码和响应内容,直接对比后端要求就能找到问题所在。
内容的提问来源于stack exchange,提问作者Mojtaba Shirkhani

