如何在Kotlin侧正确解包Jackson序列化的Map<LocalDate,BigDecimal>属性
核心问题说明
JSON 中的键值对映射结构对应的是JsonObject类型,你之前用.jsonArray获取属性的逻辑本身和结构不匹配,所以无法正常解析转换。
手动解析的正确实现
class Receiver { ... // 原有序列化合法性校验逻辑 val json = input.decodeJsonElement().jsonObject ... // 原有非空校验逻辑 // 1. 先判断字段是否存在,转换为JsonObject类型 val dateToAmountMapJson = json["dateToAmountMap"]?.jsonObject ?: throw IllegalArgumentException("dateToAmountMap 字段不能为空或类型不匹配") // 2. 遍历JsonObject的键值对做类型转换 val dateToAmountMap: Map<LocalDate, BigDecimal> = dateToAmountMapJson.entries.associate { (dateStr, valueEle) -> // 注意不能直接强转JsonElement为BigDecimal,需要先取原始值再构造 LocalDate.parse(dateStr) to BigDecimal(valueEle.jsonPrimitive.content) } }
更简洁的工程化方案
不需要手动拆解JsonElement,直接用序列化框架一键反序列化整个对象即可:
- 如果使用kotlinx.serialization,先定义对应的数据类:
@Serializable data class ResponseA( val dateToAmountMap: Map<@Serializable(LocalDateSerializer::class) LocalDate, @Serializable(BigDecimalSerializer::class) BigDecimal> ) // 接收侧直接反序列化 val a = input.decodeFromString<ResponseA>() val dateToAmountMap = a.dateToAmountMap
- 如果使用Jackson作为序列化框架,只需要注册Javatime模块和Kotlin模块,直接调用
objectMapper.readValue(input, A::class.java)反序列化Java侧对应的A类实例即可,不需要手动处理字段解析。
内容的提问来源于stack exchange,提问作者Ademord
相关产品推荐
相关产品推荐

