Retrofit调用News API请求成功但response.body()为空的排查求助
News API请求空指针异常解决方案
问题概述
调用News API的top-headlines接口时,响应返回200状态码,但执行newsItems.addAll(response.body().get_articles())触发空指针异常,堆栈信息显示Collection.toArray()调用在null对象上。
核心原因
- 字段映射不匹配:API返回字段为
status、totalResults、articles,但实体类字段命名为_status、_totalResults、_articles,Gson默认无法完成字段映射。 - 缺少无参构造函数:Gson反序列化需要无参构造函数实例化对象,当前实体类仅提供带参构造,导致反序列化失败,部分字段返回null。
- 集合类型兼容性问题:使用
ArrayList具体类而非List接口,Gson反序列化时兼容性较差。
修复步骤
1. 修正实体类字段映射与构造函数
给实体类字段添加@SerializedName注解匹配API字段,同时添加无参构造函数:
NewsApiResponse类修改
import com.google.gson.annotations.SerializedName; import java.util.List; public class NewsApiResponse { @SerializedName("status") private String _status; @SerializedName("totalResults") private int _totalResults; @SerializedName("articles") private List<NewsItem> _articles; // 添加无参构造 public NewsApiResponse() {} public NewsApiResponse(String _status, int _totalResults, List<NewsItem> _articles) { this._status = _status; this._totalResults = _totalResults; this._articles = _articles; } // 保留原有getter/setter方法 public String get_status() { return _status; } public void set_status(String _status) { this._status = _status; } public int get_totalResults() { return _totalResults; } public void set_totalResults(int _totalResults) { this._totalResults = _totalResults; } public List<NewsItem> get_articles() { return _articles; } public void set_articles(List<NewsItem> _articles) { this._articles = _articles; } }
NewsItem类修改
import com.google.gson.annotations.SerializedName; public class NewsItem { @SerializedName("author") private String _author; @SerializedName("title") private String _title; @SerializedName("description") private String _description; @SerializedName("url") private String _url; @SerializedName("urlToImage") private String _urlToImage; @SerializedName("publishedAt") private String _publishedAt; // 添加无参构造 public NewsItem() {} public NewsItem(String _author, String _title, String _description, String _url, String _urlToImage, String _publishedAt) { this._author = _author; this._title = _title; this._description = _description; this._url = _url; this._urlToImage = _urlToImage; this._publishedAt = _publishedAt; } }
2. 增加空值判断避免崩溃
在onResponse方法中提前检查空值,防止触发异常:
private void findNews() { NewsApiUtilities.getApiInterface().getNews(country,100, apiKey).enqueue(new Callback<NewsApiResponse>() { @Override public void onResponse(Call<NewsApiResponse> call, Response<NewsApiResponse> response) { if (response.isSuccessful() && response.body() != null) { List<NewsItem> articles = response.body().get_articles(); if (articles != null && !articles.isEmpty()) { newsItems.addAll(articles); adapter.notifyDataSetChanged(); } } } @Override public void onFailure(Call<NewsApiResponse> call, Throwable t) { t.printStackTrace(); // 打印错误栈便于排查 } }); }
3. 验证请求合法性
确认以下参数有效:
- API密钥未过期、未超出调用限额
country参数为合法值(如"us")pageSize未超过API限制(最大值100,当前设置符合要求)
调试技巧
若问题仍存在,可打印原始响应体查看API实际返回内容:
@Override public void onResponse(Call<NewsApiResponse> call, Response<NewsApiResponse> response) { if (response.isSuccessful()) { try { String rawResponse = response.raw().body().string(); Log.d("NewsApiDebug", "原始响应内容: " + rawResponse); } catch (IOException e) { e.printStackTrace(); } // 后续逻辑... } }
内容的提问来源于stack exchange,提问作者Bosko
相关产品推荐
相关产品推荐

