杰克逊忽略不是布尔值但名称以 "is" 开头的数据类字段



我在我的项目中使用 Jackson 和 Kotlin 绑定。我们有一个数据类,它有一个类型为Map<A, B>的字段,名为"isRecommendation"。当 Jackson 序列化数据类时,生成的 JSON 字符串中会省略此字段。

重现相同行为的简单测试:

class FooKotlin {
@Test
fun testFoo() {
println(jacksonObjectMapper().writeValueAsString(Foo1(true)))
println(jacksonObjectMapper().writeValueAsString(Foo2(1)))
println(jacksonObjectMapper().writeValueAsString(Foo3("true")))
}
}
data class Foo1(val isFoo: Boolean)
data class Foo2(val isFoo: Int)
data class Foo3(val isFoo: String)

控制台打印:

{"foo":true}
{}
{}

当我反编译 Kotlin 字节码时,除了字段的类型之外,这三个类似乎具有几乎相同的内容。那么杰克逊这种行为的原因是什么呢?

正如@chrsblck所提到的,它与杰克逊模块-Kotlin 问题 #80 有关

在版本 2.10.1 上,它不可重现,尽管序列化的属性名称不同(不会删除"is"前缀(:

{"isFoo":true}
{"isFoo":1}
{"isFoo":"true"}

在早期版本中,可以使用JsonProperty注释修复此问题:

data class Foo1(val isFoo: Boolean)
data class Foo2(@get:JsonProperty("foo") val isFoo: Int)
data class Foo3(@get:JsonProperty("foo") val isFoo: String)
{"foo":true}
{"foo":1}
{"foo":"true"}

从技术上讲,将非布尔属性命名为"isSomthing"是不正确的,并且违反了JavaBeans规范。杰克逊依赖于JavaBeans约定,因此它变得混乱。

如果你能避免这样的命名,我建议这样做。否则,从 Java 代码调用 Foo* 类时可能会遇到同样的问题。

相关内容

最新更新