Spring Boot中如何将动态JS对象二维数组转换为Kotlin可识别类型
问题描述
向基于Kotlin开发的Spring Boot应用发送特定格式JSON,数据为对象构成的二维数组,每个对象包含字符串类型的动态键与整数类型的值,结构示例如下:
[ [ {"-1": 272}, {"2": 0}, {"apple": -1}, {"apple": -1} ], [ {"1": 20}, {"-1": 2}, {"orange": 1} ] ]
前端定义的对应数据类型如下:
interface Thing { [item: number | string]: number }
此前尝试两种接收方案均失败:
- 使用Kotlin
List<List<Any>>类型接收,因对象键为动态,无法直接获取键对应的值 - 尝试映射为Kotlin
Pair<Any, Integer>类型,Spring Boot内置的ObjectMapper(Jackson)无法完成正确的参数映射
正确实现方案
不需要自定义复杂的反序列化逻辑,直接用Map作为内层对象的接收类型即可,Jackson默认支持动态键值对JSON对象到Map的反序列化,最终接参类型定义如下:
// 直接作为Controller层@RequestBody的参数类型使用即可 typealias ThingData = List<List<Map<String, Int>>>
方案说明
- JSON规范中对象的键只能是字符串类型,前端TS定义里
number | string的联合类型在序列化时会自动把数字键转为字符串,因此Kotlin侧统一用String声明键的类型不会出现数据丢失或转换错误 - 此前用
List<List<Any>>接收时,内层对象实际会被Jackson反序列化为LinkedHashMap<String, Int>实例,但因声明类型为Any,使用时需要手动强转,既不类型安全也容易触发类型转换异常 Pair类型无法直接接收单键JSON对象,Jackson默认没有对应的自动转换规则,额外写适配规则性价比极低
接口使用示例
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController @RestController class DemoController { @PostMapping("/thing/upload") fun handleThingUpload(@RequestBody data: List<List<Map<String, Int>>>) { // 直接遍历处理数据即可 data.forEach { innerGroup -> innerGroup.forEach { singleItem -> // 获取键值对示例 singleItem.forEach { (key, value) -> // 业务逻辑:如果需要把数字格式的key转回Int,在这里判断转换即可 println("key: $key, value: $value") } } } } }
内容的提问来源于stack exchange,提问作者John M
相关产品推荐
相关产品推荐

