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
相关产品推荐
相关产品推荐

