求助:Kotlin委托属性Jackson反序列化失败的解决办法
解决Kotlin委托属性数据类的Jackson反序列化问题
问题核心在于:Jackson默认会尝试寻找与ExtendedResponseDto构造参数base对应的JSON字段,但你的JSON结构里并没有名为base的嵌套对象,而是把name/age和city平级放置,导致无法匹配非空的base参数,抛出缺失参数异常。
简便解决方案:自定义带@JsonCreator的构造函数
通过手动指定构造函数的参数映射,让Jackson知道如何从平级的JSON字段中构建base委托对象和当前类的额外字段:
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION, defaultImpl = BaseResponseDto::class) interface ResponseDto { val name: String val age: Int } data class BaseResponseDto( override val name: String, override val age: Int, ) : ResponseDto data class ExtendedResponseDto( private val base: ResponseDto, val city: String, ) : ResponseDto by base { // 自定义构造函数,用于Jackson反序列化 @JsonCreator constructor( @JsonProperty("name") name: String, @JsonProperty("age") age: Int, @JsonProperty("city") city: String ) : this(BaseResponseDto(name, age), city) } // 测试代码 val json = """{ "name": "Thomas", "age": 3, "city": "Paris" }""" val mapper = jacksonObjectMapper() val dto = mapper.readValue<ExtendedResponseDto>(json) println(dto.name) // 输出 Thomas println(dto.age) // 输出 3 println(dto.city) // 输出 Paris
为什么@JsonUnwrapped不生效?
@JsonUnwrapped主要用于将嵌套对象的字段展开到父级JSON中,但它只作用于类的属性,而非构造函数参数。你的base是构造参数,且类通过委托实现接口而非直接持有字段,因此@JsonUnwrapped无法让Jackson自动将平级字段映射到base参数。
其他可选方案
如果不想自定义构造函数,也可以编写自定义JsonDeserializer,手动解析JSON节点并构建ExtendedResponseDto实例,但自定义构造函数的方式更简洁,且符合Kotlin数据类的设计习惯。
内容的提问来源于stack exchange,提问作者Hugo Caupert
相关产品推荐
相关产品推荐

