You need to enable JavaScript to run this app. 使用Retrofit2请求iTunes音乐视频搜索接口报类型解析错误
优惠活动
大模型
产品
解决方案
定价
更多

使用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实体类字段定义和接口返回结构完全匹配,不需要修改,只需要调整接口定义和请求逻辑即可:

  1. 修改ApiService接口定义
    把POST请求替换为GET请求,用@Query注解传递查询参数,返回类型替换为和接口结构匹配的单个Video对象:
    public interface ApiService {
        @GET("search")
        Call<Video> getTracks(@Query("term") String keyword, @Query("media") String mediaType);
    }
    
  2. 修改页面类的请求调用逻辑
    去掉手动拼接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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.04 13:45:01