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

Kotlin访问嵌套JSON的name字段报错:Expected BEGIN_ARRAY but was BEGIN_OBJECT

解决Moshi+Retrofit解析嵌套JSON时的类型不匹配错误

问题重现

运行代码时抛出错误:Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $,核心原因是接口返回的JSON根结构为对象(外层是{}),但代码错误地将接口返回类型声明为数组。

错误原因分析

给定的JSON根结构是一个包含results数组的对象:

{ 
   "results":[
      {
         "id":1,
         "name":"Rick Sanchez",
         "status":"Alive",
         "species":"Human",
         "type":"",
         "gender":"Male"
      }
   ]
}

原ApiService中getMovies()的返回类型被定义为List<Movie>,这会让Retrofit尝试将返回的JSON解析为数组([]),与实际的对象结构不匹配,直接导致解析失败。

修复步骤

1. 修正ApiService的返回类型

将接口方法的返回类型从List<Movie>改为Movie,匹配JSON的根对象结构:

interface MovieApiService {
    @GET("character")
    suspend fun getMovies(): Movie // 替换List<Movie>为Movie
}

2. 调整ViewModel中的数据处理逻辑

获取到Movie对象后,通过其results属性访问嵌套的列表,进而提取每个MovieDetail的name字段:

private fun getMovies() {
    viewModelScope.launch {
        try {
            val movieResult = MovieApi.retrofitService.getMovies()
            // 提取所有name字段
            val nameList = movieResult.results.map { it.name }
            _status.value = "Success: ${nameList.size} names retrieved\n${nameList.joinToString("\n")}"
        } catch (e: Exception) {
            _status.value = "请求失败:${e.message}"
        }
    }
}

3. 数据类无需修改

原有的Movie和MovieDetail数据类已经正确映射了JSON的嵌套结构,保持不变即可:

data class Movie(
    @Json(name = "results") val results: List<MovieDetail>
)
data class MovieDetail(
    @Json(name = "name") val name: String
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:30:44