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

