Jackson注解在含Kotlin内联值类字段的类中失效,如何修复?
Jackson处理含内联值类的类时@JsonProperty注解失效的解决办法
当Kotlin类中包含@JvmInline标记的内联值类属性时,Jackson会忽略该类所有字段上的@JsonProperty注解,导致序列化后的JSON字段名无法按注解指定的名称生效。
复现代码
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper data class MyDataClass(val value: String) @JvmInline value class MyInlineClass(val value: String) data class ClassUsingMyDataClass( @JsonProperty("fred") val myInlineClassField: MyDataClass, @JsonProperty("barney") val myStringField: String ) data class ClassUsingMyInlineClass( @JsonProperty("fred") val myInlineClassField: MyInlineClass, @JsonProperty("barney") val myStringField: String ) fun main() { val objectMapper = jacksonObjectMapper() // 按预期输出 {"fred":{"value":"one"},"barney":"two"} println(objectMapper.writeValueAsString(ClassUsingMyDataClass(MyDataClass("one"), "two"))) // 实际输出 {"myInlineClassField":"one","myStringField":"two"},未使用注解指定的字段名 println(objectMapper.writeValueAsString(ClassUsingMyInlineClass(MyInlineClass("one"), "two"))) }
解决方法
方法1:给内联类的value字段添加@JsonValue注解
直接在内联类的value属性上标记@JsonValue,告诉Jackson将内联类直接序列化为其内部值,同时保留宿主类字段的@JsonProperty注解:
import com.fasterxml.jackson.annotation.JsonValue @JvmInline value class MyInlineClass(@JsonValue val value: String)
修改后重新运行,ClassUsingMyInlineClass的序列化结果会变为预期的{"fred":"one","barney":"two"}。
方法2:配置ObjectMapper启用INLINE_CLASS_AS_VALUE特性
在初始化jacksonObjectMapper时,启用Kotlin模块的INLINE_CLASS_AS_VALUE特性,该特性会让Jackson正确处理内联类的同时,保留宿主类字段的注解:
import com.fasterxml.jackson.module.kotlin.KotlinFeature import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper fun main() { val objectMapper = jacksonObjectMapper { enable(KotlinFeature.INLINE_CLASS_AS_VALUE) } // 输出符合预期的 {"fred":"one","barney":"two"} println(objectMapper.writeValueAsString(ClassUsingMyInlineClass(MyInlineClass("one"), "two"))) }
注:Jackson 2.18.x版本中该特性默认可能已启用,但显式配置可以确保行为一致,同时需保证Jackson核心库与Kotlin模块版本统一(均为2.18.2)。
内容的提问来源于stack exchange,提问作者Klitos Kyriacou
相关产品推荐
相关产品推荐

