Jackson Kotlin反序列化异常:无法从START_OBJECT解析ArrayList
解决Jackson Kotlin解析Fitbit JSON时跳过外层字段的问题
你遇到的问题很典型:JSON的根节点是一个包含数组的对象,但你直接尝试反序列化成List<ActivitiesSteps>,Jackson自然会报错——它期望看到数组的起始符号[,但实际拿到的是对象的{。下面给你两种简单可行的解决方案:
方案一:创建外层响应数据类(推荐,类型安全)
最直观的方式是定义一个对应整个JSON结构的数据类,把外层的activities-steps字段包含进来,然后从中提取你需要的列表:
// 外层响应类,注意字段名的横杠要用反引号包裹(Kotlin标识符不允许直接包含横杠) data class StepsResponse(val `activities-steps`: List<ActivitiesSteps>) // 你原来的ActivitiesSteps保持不变 data class ActivitiesSteps(var dateTime: String, var value: String)
然后修改解析代码:
val mapper = jacksonObjectMapper() val stepsResponse = mapper.readValue<StepsResponse>(jsonSteps) val stepsList: List<ActivitiesSteps> = stepsResponse.`activities-steps`
这种方式结构清晰,编译时就能检查类型错误,非常适合长期维护的代码。
方案二:用JsonNode直接提取数组(灵活,无需额外类)
如果不想新增数据类,可以先用Jackson的树模型解析整个JSON,再定位到目标数组节点进行转换:
val mapper = jacksonObjectMapper() // 先解析成JsonNode树形结构 val rootNode = mapper.readTree(jsonSteps) // 获取"activities-steps"对应的数组节点 val stepsArrayNode = rootNode.get("activities-steps") // 将数组节点转换为List<ActivitiesSteps> val stepsList = mapper.convertValue( stepsArrayNode, object : TypeReference<List<ActivitiesSteps>>() {} )
或者用Kotlin的扩展函数简化写法:
val stepsList = rootNode["activities-steps"] .traverse(mapper) .readValueAs<List<ActivitiesSteps>>()
这种方式不需要定义额外类,适合临时的、简单的解析场景。
两种方案都能完美解决你的问题,根据自己的代码场景选择就好啦~
内容的提问来源于stack exchange,提问作者Ángel Rodríguez
相关产品推荐
相关产品推荐

