当某个类包含一个内联值类的属性时,Jackson 会忽略附加到封闭类的任何字段的所有注释。最小可重现示例:
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()
// Prints {"fred":{"value":"one"},"barney":"two"} as expected
println(objectMapper.writeValueAsString(ClassUsingMyDataClass(MyDataClass("one"), "two")))
// Prints {"myInlineClassField":"one","myStringField":"two"}, why doesn't it use fred and barney?
println(objectMapper.writeValueAsString(ClassUsingMyInlineClass(MyInlineClass("one"), "two")))
}
@JsonProperty
一旦包含了一个类型为内联值类的字段,有没有办法可以再次工作?
我正在使用 Jackson 2.18.2 和 Kotlin 2.1.10。
注释
@JsonProperty
被应用于主构造函数的参数,仅仅是因为它可以这样做。当有多个注释目标适用时,请参阅本文档最后一部分,了解在何处应用注释的优先级。这一切都可以通过常规方式正常工作
data class
- Jackson 可以在构造函数参数上检测到这些注释。但是,一旦使用内联类作为构造函数参数,就会生成两个构造函数。在 Java 中,它们看起来像这样:
注释
JsonProperty
仅添加到第二个重载中。我不确定这种行为是否是故意的。这是 YouTrack 上的相关错误报告。无论如何,为了使其工作,您只需用注释标记字段即可。
Kotlin 还会生成一个
myInlineClassField
名称混乱的 getter(请参阅此处的原因)。这会让 Jackson 有点困惑,并导致它为 getter 编写一个额外的 JSON 属性,因此您需要JsonIgnore
getter。