Android中Retrofit 2调用API返回200但响应体为Null求助
我来帮你排查这个头疼的问题——状态码明明是200,但响应体始终为Null。结合你给出的JSON响应、Retrofit配置和POJO代码,我整理了几个最可能的原因和对应的解决办法:
1. 字段类型不匹配(最可能的元凶)
你看,JSON响应里的status是数字类型(200),但在Resonse内部类里,你把status定义成了String类型:
@SerializedName("status") @Expose private String status;
Gson默认没法直接把数字转成String,这会导致整个响应解析失败,最终返回Null。
修复方案:
把status字段的类型改成int(或者Integer),对应的getter和setter也要同步修改:
@SerializedName("status") @Expose private int status; public int getStatus() { return status; } public void setStatus(int status) { this.status = status; }
2. JSON响应存在语法错误
仔细看你的JSON响应,result数组里最后一个元素的末尾多了个逗号:
"video_category": "News/Politics", }
这个多余的逗号属于无效JSON语法,虽然Gson在宽松模式下能容忍,但严格模式下会直接解析失败。
修复方案:
- 优先建议后端同学修复这个JSON语法问题;
- 如果暂时没法改后端,可以给Gson配置宽松模式,让它忽略这类小错误:
Gson gson = new GsonBuilder() .setLenient() // 开启宽松模式 .create(); // 在Retrofit构建时使用这个自定义的Gson实例 retrofit = new Retrofit.Builder() .baseUrl(API_BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .client(client) .build();
3. 实体类拼写或注解错误
你的ResponseVideoList里定义的列表是List<VIdeoItem> result,注意这里的类名是VIdeoItem(大写的I),如果你的实际实体类是VideoItem(小写的i),或者VIdeoItem类里的字段@SerializedName和JSON里的键不匹配(比如把video_id写成videoId却没加注解),都会导致解析失败。
修复方案:
- 检查
VIdeoItem的类名拼写是否完全正确; - 确保
VIdeoItem的每个字段都正确添加了@SerializedName,和JSON里的键完全对应:
public class VIdeoItem implements Serializable { @SerializedName("video_id") @Expose private String videoId; @SerializedName("video_title") @Expose private String videoTitle; // 其他字段同理,一一对应JSON里的键 }
4. 开启日志拦截器排查细节
有时候光看代码找不到问题,最好的办法是看实际的请求和响应内容,以及解析时的错误日志。你可以给OkHttpClient加一个日志拦截器:
操作步骤:
首先添加依赖(如果还没加):
implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
然后修改OkHttpClient的配置:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); // 打印完整的请求响应内容 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(logging) // 添加日志拦截器 .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request newRequest = chain.request().newBuilder() .addHeader("Authorization", "Bearer " + token) .build(); return chain.proceed(newRequest); } }) .build();
运行后看Logcat,你能看到完整的响应JSON,以及Gson解析时的错误信息,这样就能精准定位问题了。
5. 确认请求体符合后端要求
虽然状态码是200说明服务器接收了请求,但如果你的请求体不符合后端的预期,后端可能返回一个格式异常的响应,导致解析失败。通过上面的日志拦截器,你可以看到实际发送的请求体,确认是否和后端要求一致。
内容的提问来源于stack exchange,提问作者Sushrita

