使用Retrofit2请求iTunes音乐视频搜索接口报类型解析错误
解析错误触发原因
控制台抛出的Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 4 column 2 path $ 本质是Gson解析器的结构类型不匹配错误:解析器按照你定义的响应类型,预期在JSON根节点拿到数组格式([]开头),但实际接口返回的根节点是标准JSON对象格式({}开头),无法完成类型转换直接抛错。
代码中的具体问题点
1. 响应类型定义和接口返回结构完全错配
你在ApiService中定义的返回值是Call<List<Video>>,代表解析器会把返回结果的根节点当成Video类型的数组处理。
但本次对接的iTunes搜索接口,返回的根节点本身就是单个JSON对象,结构完全匹配你已经写好的Video实体类(包含根层级的resultCount、results两个字段),根本不是数组结构,这是触发报错的直接原因。
2. 请求方式和参数传递逻辑不符合接口规范
- 你在接口中使用
@POST("search")搭配@Body JsonObject传参,但该搜索接口是标准GET请求接口,需要将参数拼接为URL查询参数传递,不支持请求体传参的POST逻辑。 - 手动拼接的
JsonObject参数中,把term值写成了带URL编码的"Michael+jackson",当作为请求体传递时会被二次编码,容易导致服务端返回异常响应,但这不是本次解析报错的核心诱因。
3. 回调逻辑的类型强转存在运行时崩溃风险
就算忽略前面的结构错配,你在成功回调里写的Video video = (Video) response.body(); 也会直接触发类型转换异常:因为你的回调泛型定义为List<Video>,response.body()的实际类型是Video列表,无法强转成单个Video对象。
对应修复方案
你的Video、Result实体类字段定义和接口返回结构完全匹配,不需要修改,只需要调整接口定义和请求逻辑即可:
- 修改ApiService接口定义
把POST请求替换为GET请求,用@Query注解传递查询参数,返回类型替换为和接口结构匹配的单个Video对象:public interface ApiService { @GET("search") Call<Video> getTracks(@Query("term") String keyword, @Query("media") String mediaType); } - 修改页面类的请求调用逻辑
去掉手动拼接JsonObject当请求体的冗余逻辑,直接把参数传递给GET方法,同步修正回调泛型和强转逻辑:private void load(){ Retrofit retrofit = RetrofitClient.getInstance(); ApiService apiService = retrofit.create(ApiService.class); Call<Video> videoCall = apiService.getTracks("Michael jackson", "musicVideo"); videoCall.enqueue(new Callback<Video>() { @Override public void onResponse(Call<Video> call, Response<Video> response) { if(response.isSuccessful() && response.body() != null){ Video video = response.body(); Log.d("list", String.valueOf(video.getResultCount())); // 后续可通过video.getResults()拿到视频列表数据 } } @Override public void onFailure(Call<Video> call, Throwable t) { Log.d("error",t.getMessage()); Toast.makeText(getActivity(),t.getMessage(),Toast.LENGTH_LONG).show(); } }); }
内容的提问来源于stack exchange,提问作者Digvijay Singh Thakur
相关产品推荐
相关产品推荐

