Jackson Databind 2.17+中@JsonAnySetter失效?如何恢复旧行为?
问题解答
是的,@JsonAnySetter的行为在Jackson 2.17版本确实发生了变更,核心原因是Jackson Kotlin模块对Kotlin数据类中只读属性(val)的处理逻辑变得更严格了。
在2.15.x版本中,即使otherContent是val修饰的Map属性,Jackson会默认将其视为可修改的容器,自动把未知字段填充进去。但2.17版本开始,Jackson严格遵循Kotlin的属性可变性规则:val标记的属性是只读的,无法直接通过Setter修改,因此不再自动将未知字段映射到这个Map中,导致最终otherContent为空。
修复方案(任选其一即可)
方案1:将属性改为可变类型(
var)
把otherContent的val改成var,同时明确使用可变Map类型,让Jackson可以直接修改这个容器:@JsonIgnoreProperties(ignoreUnknown = true) data class MyDTO(val type: String, @JsonAnySetter var otherContent: MutableMap<String, String> = HashMap())方案2:保留
val,添加专门的@JsonAnySetter方法
如果想保持属性只读,可以单独写一个方法来处理未知字段,手动填充到otherContent中:@JsonIgnoreProperties(ignoreUnknown = true) data class MyDTO(val type: String, val otherContent: MutableMap<String, String> = HashMap()) { @JsonAnySetter fun addToOtherContent(key: String, value: String) { otherContent[key] = value } }方案3:恢复旧版行为(不推荐)
通过配置强制Jackson将只读属性当作Setter使用,不过这种方式可能在后续版本中被移除,兼容性较差:val objectMapper = jacksonObjectMapper().apply { configure(DeserializationFeature.USE_READ_ONLY_PROPERTY_AS_SETTER, true) }
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

