Jackson中向ObjectNode添加ArrayNode出现类型转换报错如何解决
问题解决
错误原因
- 你预期的JSON结构本身存在语法错误:JSON数组是仅存储值的有序集合,不支持直接存放
"课程名": {成绩对象}这类键值对结构。你示例里写的courses数组实际应该是对象类型,或者调整数组元素结构为包含课程名、成绩的单个对象。 - 代码逻辑错误:你调用了
ArrayNode.set(键, 值),该方法是ObjectNode独有方法,ArrayNode的set方法仅支持按索引位置修改元素,执行该操作时实际返回的是ObjectNode实例,你强制转换为ArrayNode就会触发类型转换异常。 - 冗余操作:你创建了两个完全相同的
ObjectMapper实例,属于不必要的资源浪费。
解决方案
方案1:调整courses为对象类型(和你预期的结构逻辑一致)
如果不需要数组,直接用courses对象存课程名和对应成绩,代码如下:
val objectMapper = ObjectMapper() val rootNode = objectMapper.createObjectNode() result?.forEach { (username, courses) -> // 转换Courses实例为JsonNode val coursesNode = objectMapper.valueToTree<JsonNode>(courses) // 创建用户节点 val userNode = objectMapper.createObjectNode() // 创建courses对象节点 val coursesObjNode = objectMapper.createObjectNode() // 遍历Courses的所有属性 coursesNode.fields().forEachRemaining { (courseName, gradeValue) -> // 过滤空值(如果不需要可以去掉该判断) if (!gradeValue.isNull) { val gradeNode = objectMapper.createObjectNode() gradeNode.put("grade", gradeValue.asInt()) coursesObjNode.set(courseName, gradeNode) } } userNode.set("courses", coursesObjNode) rootNode.set(username, userNode) } // 输出最终JSON println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode))
生成的合法JSON结构如下:
{ "user1": { "courses": { "Math": { "grade": 1 }, "English": { "grade": 1 } } }, "user2": { "courses": {} } }
方案2:保留courses为数组类型
如果必须用数组,调整结构为每个元素存课程名和成绩,代码如下:
val objectMapper = ObjectMapper() val rootNode = objectMapper.createObjectNode() result?.forEach { (username, courses) -> val coursesNode = objectMapper.valueToTree<JsonNode>(courses) val userNode = objectMapper.createObjectNode() // 创建courses数组节点 val coursesArrayNode = objectMapper.createArrayNode() coursesNode.fields().forEachRemaining { (courseName, gradeValue) -> if (!gradeValue.isNull) { val courseItemNode = objectMapper.createObjectNode() courseItemNode.put("name", courseName) courseItemNode.put("grade", gradeValue.asInt()) coursesArrayNode.add(courseItemNode) } } userNode.set("courses", coursesArrayNode) rootNode.set(username, userNode) }
生成的JSON结构如下:
{ "user1": { "courses": [ { "name": "Math", "grade": 1 }, { "name": "English", "grade": 1 } ] } }
内容的提问来源于stack exchange,提问作者Mike M
相关产品推荐
相关产品推荐

