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

如何将Google Sheets API返回的JSON片段转为UserDataModel对象列表?

问题:Google Sheets API返回的二维数组转UserDataModel列表失败

我需要处理Google Sheets API返回的JSON数据,其中values字段是二维数组,要把每个子数组转换为UserDataModel对象并组成列表。

定义的数据类:

data class UserDataModel(var point:String?, var get: String?, var take: String?, var isSelected: Boolean = false)

当前实现代码(在ActivityChoosing.kt的getDataFromAPI方法中):

val json = JSONObject(DATA_FROM_SHEETS)
val gson = Gson()
val model_list = gson.fromJson(json["values"].toString() , Array<UserDataModel>::class.java)

执行时抛出异常:

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 3 path $[0]

解决方案

问题原因

Google Sheets API返回的values是二维字符串数组(例如[["P1","G1","T1"], ["P2","G2","T2"]]),而Gson默认会将每个子数组解析为键值对结构的对象,但子数组本身是无键的序列,因此触发类型不匹配的异常。

方法1:手动遍历转换(简单直接)

直接遍历二维数组的每一行,根据索引映射到UserDataModel的字段:

val json = JSONObject(DATA_FROM_SHEETS)
val values = json.getJSONArray("values")
val modelList = mutableListOf<UserDataModel>()

for (i in 0 until values.length()) {
    val row = values.getJSONArray(i)
    // 处理行长度不足的情况,避免数组越界
    val point = if (row.length() > 0) row.getString(0) else null
    val get = if (row.length() > 1) row.getString(1) else null
    val take = if (row.length() > 2) row.getString(2) else null
    modelList.add(UserDataModel(point, get, take))
}

方法2:自定义Gson TypeAdapter(适合复用场景)

创建自定义的TypeAdapter,告诉Gson如何将数组序列/反序列化为UserDataModel对象:

class UserDataModelTypeAdapter : TypeAdapter<UserDataModel>() {
    override fun write(out: JsonWriter, value: UserDataModel?) {
        // 序列化逻辑(按需实现,此处仅展示反序列化)
        out.beginArray()
        out.value(value?.point)
        out.value(value?.get)
        out.value(value?.take)
        out.endArray()
    }

    override fun read(`in`: JsonReader): UserDataModel {
        `in`.beginArray()
        // 按顺序读取数组元素,处理可能的缺失值
        val point = if (`in`.hasNext()) `in`.nextString() else null
        val get = if (`in`.hasNext()) `in`.nextString() else null
        val take = if (`in`.hasNext()) `in`.nextString() else null
        `in`.endArray()
        return UserDataModel(point, get, take)
    }
}

使用该Adapter进行解析:

val gson = GsonBuilder()
    .registerTypeAdapter(UserDataModel::class.java, UserDataModelTypeAdapter())
    .create()

val json = JSONObject(DATA_FROM_SHEETS)
val valuesJson = json["values"].toString()
val modelList = gson.fromJson(valuesJson, Array<UserDataModel>::class.java).toList()

内容的提问来源于stack exchange,提问作者Юля Муравьева

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:13:24