You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin使用Retrofit请求接口报错Expected BEGIN_ARRAY but was BEGIN_OBJECT

问题原因

你遇到的RETROFIT Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $报错,核心是API返回的JSON结构和你定义的接收类型不匹配:

  • 之前使用的crypto数据源根节点直接是JSON数组,所以用Response<ArrayList<MovieModel>>接收可以正常解析
  • episodate的most-popular接口根节点是JSON对象,结构如下:
{
  "page": 1,
  "pages": 100,
  "total": "2000",
  "tv_shows": [
    {"name": "The Flash", /* 其他字段 */},
    /* 更多剧集数据 */
  ]
}

你直接用数组类型接收根节点的对象,就会触发类型不匹配的崩溃。

修复方案

需要按接口返回结构调整三层代码:

1. 新增根响应包裹类

定义和根JSON结构匹配的包裹类,包含实际存储数据的剧集数组:

data class PopularShowResponse(
    val page: Int,
    val pages: Int,
    val total: String,
    // 字段名和返回的tv_shows完全对应即可,不需要的字段可以不用定义
    val tv_shows: List<MovieModel>
)

2. 修改API接口返回类型

把原有的数组返回类型替换为刚定义的根响应类:

interface MovieAPI {
    @GET("api/most-popular?page=1")
    suspend fun getData(): Response<PopularShowResponse>
}

3. 调整数据解析逻辑

从根响应对象中取出剧集数组再赋值:

private fun loadData(){
    val retrofit = Retrofit.Builder()
            .baseUrl("https://www.episodate.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(MovieAPI::class.java)

    CoroutineScope(Dispatchers.IO).launch {
        val response = retrofit.getData()
        if (response.isSuccessful){
            response.body()?.let { rootResponse ->
                Moviemodel = ArrayList(rootResponse.tv_shows)
            }
        }
        println(Moviemodel)
    }
}

内容的提问来源于stack exchange,提问作者dltayn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 21:36:03