使用Retrofit调用API时遇JSON解析错误:BEGIN_ARRAY/BEGIN_OBJECT不匹配
解决Retrofit解析错误:Expected BEGIN_ARRAY but was BEGIN_OBJECT
咱们先把这个错误的本质说透:你告诉Retrofit要接收一个电影数组(比如List<Movie>),但实际API返回的是一个JSON对象,格式完全不匹配,所以解析直接炸了。
第一步:先确认API返回的JSON结构
你先直接用浏览器或者Postman访问你的API接口,看看返回的JSON长啥样。举个常见的例子,很多API会把数据包在一个外层对象里,比如:
{ "status": "ok", "total": 10, "movies": [ {"id": 1, "title": "星际穿越", ...}, {"id": 2, "title": "盗梦空间", ...} ] }
这种情况下,外层是一个对象,真正的电影数组在movies字段里,而不是直接返回数组。
第二步:创建对应的外层响应模型
你现在只有Movie类,得再加一个用来包裹整个API响应的类,比如叫MovieResponse:
public class MovieResponse { @SerializedName("status") @Expose private String status; @SerializedName("total") @Expose private Integer total; @SerializedName("movies") // 这里要和API返回的数组字段名完全一致 @Expose private List<Movie> movies; // 记得生成getter和setter方法,或者用Lombok的@Data注解简化代码 }
第三步:修改Retrofit接口
把原来期望返回数组的接口,改成返回这个外层响应对象:
public interface MovieService { @GET("你实际的API路径") Call<MovieResponse> getMovies(); }
第四步:调整回调逻辑解析数据
调用接口的时候,先拿到外层的响应对象,再从中取出电影数组:
movieService.getMovies().enqueue(new Callback<MovieResponse>() { @Override public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) { if (response.isSuccessful() && response.body() != null) { List<Movie> movieList = response.body().getMovies(); // 这里就可以正常处理你的电影列表了 } } @Override public void onFailure(Call<MovieResponse> call, Throwable t) { // 处理请求失败的情况,比如打印错误信息 t.printStackTrace(); } });
额外检查点
- 如果API确实应该直接返回数组(比如
[{"id":1,...}, {"id":2,...}]),那你得检查是不是接口写错了,或者后端返回的格式不符合预期。 - 确保所有
@SerializedName的字段名和JSON里的键完全一致,大小写、拼写都不能错,不然也会解析失败。
内容的提问来源于stack exchange,提问作者Hải Sơn
相关产品推荐
相关产品推荐

