使用Retrofit2调用Google Books API时GSON转换报错:预期BEGIN_ARRAY却为BEGIN_OBJECT
解决Retrofit2 + GSON调用Google Books API的类型不匹配错误
这个错误ErrorExpected BEGIN_ARRAY but was BEGIN_OBJECT很常见,问题出在你定义的返回类型和Google Books API实际返回的JSON结构不匹配。
问题根源
Google Books API的返回结果并不是直接的书籍数组,而是一个包含书籍数组的顶层对象。举个例子,API返回的JSON大概是这样的:
{ "kind": "books#volumes", "totalItems": 123, "items": [ { /* 单本书的结构 */ }, { /* 另一本书的结构 */ } ] }
你现在的代码直接期望返回List<Book>(一个数组),但实际拿到的是一个包含items数组的对象,GSON自然会抛出类型不匹配的错误。
修复步骤
1. 创建顶层响应实体类
首先新建一个BookResponse类,用来匹配API的完整返回结构:
public class BookResponse { private String kind; private int totalItems; private List<Book> items; // Getter和Setter方法 public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } public int getTotalItems() { return totalItems; } public void setTotalItems(int totalItems) { this.totalItems = totalItems; } public List<Book> getItems() { return items; } public void setItems(List<Book> items) { this.items = items; } }
2. 修改API接口定义
把BookApiService里的返回类型从Call<List<Book>>改成Call<BookResponse>:
public interface BookApiService { @GET("/books/v1/volumes") Call<BookResponse> getBooks(@Query("q") String query); // 这里修改返回类型 }
3. 更新BookService中的调用逻辑
调整BookService里的getBooks方法,适配新的返回类型:
public void getBooks(String query){ final ApiResponse apiResponse = new ApiResponse(); Call<BookResponse> call = mApiService.getBooks(query); // 这里修改Call类型 call.enqueue(new Callback<BookResponse>() { // 回调类型也改成BookResponse @Override public void onResponse(Call<BookResponse> call, Response<BookResponse> response) { if (response.body() != null) { apiResponse.setBooks(response.body().getItems()); // 从response的items字段拿书籍列表 } mListener.notifyDataReceived(apiResponse); } @Override public void onFailure(Call<BookResponse> call, Throwable t) { apiResponse.setError(t); mListener.notifyDataReceived(apiResponse); } }); }
这样修改后,GSON就能正确解析API返回的JSON对象,再从中提取出书籍数组,就不会再报类型不匹配的错误了。
内容的提问来源于stack exchange,提问作者Rarity7-
相关产品推荐
相关产品推荐

