Android Retrofit2获取JSON数组时对象值为空问题求助
解决Retrofit2解析JSON数组字段为空的问题
刚用Retrofit踩过类似的坑,大概率是字段映射不匹配或者数据模型类的配置问题,我给你一步步梳理解决方法:
1. 先确认你的JSON结构(关键!)
假设你的API返回的JSON数组大概是这样:
[ { "DATA_TITLE": "第一篇文章标题", "DATA_IMAGE": "https://example.com/image1.jpg", "DATA": "文章内容1" }, { "DATA_TITLE": "第二篇文章标题", "DATA_IMAGE": "https://example.com/image2.jpg", "DATA": "文章内容2" } ]
如果是这种直接的数组结构,那我们需要先写对数据模型类。
2. 编写正确的数据模型类(核心!)
Retrofit默认用Gson解析JSON,而Gson是严格匹配字段名的——你的JSON字段是大写带下划线(比如DATA_TITLE),但Java里一般用驼峰命名(比如dataTitle),这时候必须用@SerializedName注解来指定对应关系,而且要确保字段有Getter/Setter方法(或者设为public)。
示例代码:
import com.google.gson.annotations.SerializedName; public class Article { // 用@SerializedName绑定JSON里的键名 @SerializedName("DATA_TITLE") private String dataTitle; @SerializedName("DATA_IMAGE") private String dataImage; @SerializedName("DATA") private String data; // 必须要有Getter方法,否则你拿不到字段值 public String getDataTitle() { return dataTitle; } public String getDataImage() { return dataImage; } public String getData() { return data; } // Setter可选,但建议加上,方便后续修改 public void setDataTitle(String dataTitle) { this.dataTitle = dataTitle; } public void setDataImage(String dataImage) { this.dataImage = dataImage; } public void setData(String data) { this.data = data; } }
3. 定义Retrofit的API接口
因为返回的是数组,所以接口方法的返回值是Call<List<Article>>:
import retrofit2.Call; import retrofit2.http.GET; import java.util.List; public interface ApiService { // 替换成你的实际API接口路径 @GET("articles/list") Call<List<Article>> getArticles(); }
4. 发起请求并解析响应
注意一定要添加GsonConverterFactory,这是Retrofit自动解析JSON的关键,很多新手会忘这个!
示例代码:
// 初始化Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://your-api-base-url.com/") // 替换成你的API基础地址 .addConverterFactory(GsonConverterFactory.create()) // 必须加这个!否则无法自动解析JSON .build(); // 创建API服务实例 ApiService apiService = retrofit.create(ApiService.class); // 发起异步请求 Call<List<Article>> call = apiService.getArticles(); call.enqueue(new Callback<List<Article>>() { @Override public void onResponse(Call<List<Article>> call, Response<List<Article>> response) { if (response.isSuccessful() && response.body() != null) { List<Article> articleList = response.body(); // 现在遍历列表就能拿到每个对象的字段值了 for (Article article : articleList) { Log.d("RetrofitDemo", "标题:" + article.getDataTitle()); Log.d("RetrofitDemo", "图片链接:" + article.getDataImage()); Log.d("RetrofitDemo", "内容:" + article.getData()); } } else { Log.e("RetrofitDemo", "请求成功但响应异常,状态码:" + response.code()); } } @Override public void onFailure(Call<List<Article>> call, Throwable t) { Log.e("RetrofitDemo", "请求失败:" + t.getMessage()); } });
5. 常见坑排查
如果还是字段为空,检查这几点:
- 有没有加GsonConverterFactory:没加的话,Retrofit不会自动解析JSON,你拿到的对象都是空的
- JSON结构是否匹配:如果你的API返回的是
{"code":200,"data":[{},{}]}这种包裹数组的对象,那你需要再写一个包装类,比如:
然后接口改为public class ApiResponse { @SerializedName("code") private int code; @SerializedName("data") private List<Article> articleList; public List<Article> getArticleList() { return articleList; } }Call<ApiResponse> getArticles();,解析时用response.body().getArticleList()拿数组 - 字段是否被Gson访问到:如果你的字段是private但没有Getter/Setter,Gson可能无法赋值,要么加Getter/Setter,要么把字段设为public
- @SerializedName的键名是否写错:比如把
DATA_TITLE写成了DataTitle,大小写一定要和JSON里完全一致
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

