【问题标题】:Jackson ignores data class fields that aren't boolean but are of names starting with "is"Jackson 忽略不是布尔值但名称以“is”开头的数据类字段
【发布时间】:2020-01-06 07:50:53
【问题描述】:

我在我的项目中使用Jackson with Kotlin binding。我们有一个数据类,它的字段类型为Map<A, B>,名为“isRecommended”。当 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 字节码时,除了字段的类型外,这三个类似乎具有几乎相同的内容。那么杰克逊的这种行为是什么原因造成的呢?

【问题讨论】:

标签: kotlin jackson


【解决方案1】:

正如@chrsblck 所述,它与jackson-module-kotlin issue #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 规范。 Jackson 依赖于 JavaBeans 约定,因此会感到困惑。

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

【讨论】:

    猜你喜欢
    • 2018-05-20
    • 2014-11-02
    • 2015-01-26
    • 2013-01-02
    • 1970-01-01
    • 2019-02-22
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多