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

如何编写Kotlin数据类正确解析含动态checklists字段的JSON响应

核心问题分析
  1. 服务端返回的checklists字段是动态键的映射结构,键为分类名称(如"Frequência Cardíaca"),值为对应的检查项对象,你定义的固定属性的CheckLists类完全不符合该结构
  2. 报错Expected BEGIN_OBJECT but was BEGIN_ARRAY说明服务端逻辑不一致:存在检查项时返回对象{},无检查项时返回空数组[],类型不统一导致解析失败
修正后的数据类代码

直接删除无用的CheckLists类,调整EvoData的checklists字段类型为动态Map,优先用Kotlin数据类简化写法:

import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import com.google.gson.annotations.JsonAdapter

// 根响应类
data class Evolution(
    @SerializedName("message")
    @Expose
    val message: String? = null,

    @SerializedName("data")
    @Expose
    val data: List<EvoData>? = null
)

// data数组的元素类
data class EvoData(
    @SerializedName("id")
    @Expose
    val id: Int? = null,

    @SerializedName("tipo_evolucao_id")
    @Expose
    val tipoEvolucaoId: Int? = null,

    @SerializedName("tipo_evolucao")
    @Expose
    val tipoEvolucao: String? = null,

    @SerializedName("data_hora")
    @Expose
    val dataHora: String? = null,

    @SerializedName("responsavel")
    @Expose
    val responsavel: String? = null,

    @SerializedName("evolucao")
    @Expose
    val evolucao: String? = null,

    // 核心修改:用Map接收动态键的checklists,添加自定义适配器兼容数组/对象两种格式
    @SerializedName("checklists")
    @Expose
    @JsonAdapter(ChecklistTypeAdapter::class)
    val checklists: Map<String, Checklist>? = null
)

// 单个检查分类类
data class Checklist(
    @SerializedName("label")
    @Expose
    val label: String? = null,

    @SerializedName("itens")
    @Expose
    val itens: List<Itens>? = null
)

// 检查项类
data class Itens(
    @SerializedName("pergunta")
    @Expose
    val pergunta: String? = null,

    @SerializedName("resposta")
    @Expose
    val resposta: String? = null
)
兼容类型不一致的TypeAdapter实现

新增ChecklistTypeAdapter类,处理服务端返回空数组的异常情况:

import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter

class ChecklistTypeAdapter : TypeAdapter<Map<String, Checklist>>() {
    private val gson = Gson()

    override fun write(out: JsonWriter, value: Map<String, Checklist>?) {
        // 序列化逻辑按需实现,不需要可以留空
        gson.toJson(value, object : com.google.gson.reflect.TypeToken<Map<String, Checklist>>() {}.type, out)
    }

    override fun read(reader: JsonReader): Map<String, Checklist>? {
        return when (reader.peek()) {
            // 如果是对象类型正常解析
            JsonToken.BEGIN_OBJECT -> gson.fromJson(reader, object : com.google.gson.reflect.TypeToken<Map<String, Checklist>>() {}.type)
            // 如果是数组类型(服务端无数据返回[])直接返回空Map
            JsonToken.BEGIN_ARRAY -> {
                reader.beginArray()
                reader.endArray()
                emptyMap()
            }
            else -> null
        }
    }
}

修改后即可正常解析所有返回结果,动态键会自动存入Map的key中,对应检查项存入value。


内容的提问来源于stack exchange,提问作者João Gabriel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:54:03