Android中Retrofit无法返回POJO响应,仅显示原始响应
我来帮你排查这个问题——能拿到200响应说明请求本身是通的,但解析不出ResponsePOJO,大概率是序列化/反序列化配置问题或者POJO类和接口返回的JSON结构不匹配,咱们一步步来定位:
1. 先确认Retrofit是否添加了JSON转换器
这是最容易忽略的点!如果构建Retrofit实例时没加对应的转换器,Retrofit根本不知道怎么把服务器返回的JSON转成Java对象,response.body()自然会是空。
比如用Gson作为转换器的话,构建代码必须包含这一行:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://你的服务器地址/") .addConverterFactory(GsonConverterFactory.create()) // 关键!不能少 .build();
如果你用的是Moshi/Jackson,对应换成MoshiConverterFactory或JacksonConverterFactory,同时要确保build.gradle里已经添加了对应依赖(比如Gson的依赖:implementation 'com.squareup.retrofit2:converter-gson:2.9.0',版本号建议和Retrofit本身一致)。
2. 严格匹配ResponsePOJO和服务器返回的JSON结构
这是最常见的问题!JSON的字段名、嵌套层级、数据类型必须和POJO完全对应,否则Gson(或其他转换器)无法完成映射。
举个例子:如果服务器返回的JSON是这样的:
{ "code": 200, "data": { "user_name": "张三", "user_age": 25 }, "msg": "请求成功" }
那你的ResponsePOJO就得这么写:
public class ResponsePOJO { private int code; private DataBean data; @SerializedName("msg") // 注意:如果JSON字段名和POJO字段名不一样,必须加这个注解 private String message; // 必须要有无参构造函数!转换器需要它来实例化对象 public ResponsePOJO() {} // 别忘了写Getter/Setter方法(或者用Lombok简化) public int getCode() { return code; } public void setCode(int code) { this.code = code; } // ...其他字段的Getter/Setter // 嵌套的内部类也要对应JSON的结构 public static class DataBean { @SerializedName("user_name") private String userName; @SerializedName("user_age") private int userAge; public DataBean() {} // Getter/Setter } }
重点提醒:
- 字段名不匹配时一定要加
@SerializedName注解 - 必须保留无参构造函数,否则转换器无法创建对象
- 数据类型要对应(比如JSON里是数字
25,POJO里不能用String类型)
3. 打印原始响应,确认JSON格式是否正确
你可以在onResponse里打印服务器返回的原始JSON,看看是不是符合预期:
@Override public void onResponse(Call<ResponsePOJO> call, Response<ResponsePOJO> response) { if (response.isSuccessful()) { // 打印原始响应内容 try { String rawJson = response.raw().body().string(); Log.d("RetrofitDebug", "原始响应JSON: " + rawJson); } catch (IOException e) { e.printStackTrace(); } ResponsePOJO responsePOJO = response.body(); } else { // 处理非200的响应 Log.e("RetrofitError", "响应码: " + response.code()); } }
如果打印出来的JSON有语法错误、或者结构和你写的POJO完全不符,那解析失败的原因就找到了。
4. 检查ApiInterface的定义是否正确
确保接口方法的请求方式、参数注解和服务器要求一致:
public interface ApiInterface { @POST("GetData") // 路径要和服务器接口完全匹配 Call<ResponsePOJO> sendField(@Body RequestPOJO requestPojo); // 用@Body传JSON请求体,对应服务器的接收方式 }
如果服务器要求的是表单提交(而非JSON请求体),那应该换成@FormUrlEncoded+@Field注解,而不是@Body。
按照这几步排查,基本就能解决解析失败的问题了。
内容的提问来源于stack exchange,提问作者Kumar

