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

Retrofit解析嵌套数组JSON报错:Expected BEGIN_OBJECT but was BEGIN_ARRAY

问题分析

报错Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $[0]的核心原因是数据类/接口返回类型和实际JSON结构不匹配:

  • 你期望根数组的元素是PlayerData对象,但实际返回的JSON根数组的每个元素是另一个数组(嵌套数组结构:[[PlayerInfo对象], [PlayerInfo对象], ...])
  • 额外定义的PlayerData、Player数据类完全多余,因为JSON里没有对应的team、player键值对,直接是数组嵌套数组。
修正步骤

1. 调整API接口返回类型

修改ConnectedSleeper接口的返回类型,匹配JSON的List<List<PlayerInfo>>嵌套结构:

interface ConnectedSleeper {
    @GET("nflTeamDataArray")
    fun getPlayerData(): Call<List<List<PlayerInfo>>> // 改为嵌套列表类型

    // 其余代码保持不变
    companion object{
        private const val BASE_URL =  "http://10.0.2.2:8080/"
        fun create(): ConnectedSleeper {
            return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(MoshiConverterFactory.create())
                .build()
                .create(ConnectedSleeper::class.java)
        }
    }
}

2. 修正PlayerInfo数据类的字段错误

JSON里的age是数字类型(如38),但你定义成了String?,会导致解析失败;另外postion存在拼写错误,需修正为position:

@JsonClass(generateAdapter = true)
data class PlayerInfo(
    @Json(name = "birth_date") val birthDate: String?,
    @Json(name = "full_name") val fullName: String?,
    @Json(name = "college") val college: String?,
    @Json(name = "team") val team : String?,
    @Json(name = "position") val position: String?, // 修正拼写错误
    @Json(name = "number") val number: Int?,
    @Json(name = "age") val age: Int?, // 改为Int类型,匹配JSON的数字格式
    @Json(name = "weight") val weight: String?,
    @Json(name = "height") val height: String?
): java.io.Serializable

3. 移除冗余数据类

直接删除PlayerData.kt文件中的PlayerData和Player类,这两个类和实际JSON结构完全不对应,属于无效定义。

4. 调整MainActivity的响应处理逻辑

现在响应体是List<List<PlayerInfo>>,可以将嵌套列表扁平化为单一列表,方便RecyclerView使用:

sleeperConnect.getPlayerData()
    .enqueue(object : Callback<List<List<PlayerInfo>>> {
        override fun onResponse(
            call: Call<List<List<PlayerInfo>>>,
            response: Response<List<List<PlayerInfo>>>
        ) {
            if (response.isSuccessful) {
                val nestedPlayerList = response.body()
                // 将嵌套列表扁平化为单一列表
                val flatPlayerList = nestedPlayerList?.flatten() ?: emptyList()
                Log.d("Response", "onResponse: 共解析${flatPlayerList.size}个球员数据")
                // 给RecyclerView设置适配器
                val adapter = CustomAdapter(flatPlayerList)
                recyclerview.adapter = adapter
            }
        }

        override fun onFailure(call: Call<List<List<PlayerInfo>>>, t: Throwable) {
            Log.d("Draft time Activity ", "onFailure: " + t.message)
        }
    })
验证逻辑

修改完成后,Moshi会正确解析JSON结构:

  • 根数组的每个元素被识别为List<PlayerInfo>类型的数组
  • 每个子数组内的对象会匹配修正后的PlayerInfo数据类字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:17:12