Jackson忽略不是布尔类型但以”is”开头的字段。

huangapple go评论65阅读模式
英文:

Jackson ignores data class fields that aren't boolean but are of names starting with "is"

问题

我在我的项目中使用了Jackson与Kotlin绑定。我们有一个数据类,其中有一个字段的类型为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字节码时,这三个类似乎具有几乎相同的内容,除了字段的类型。那么,Jackson行为的原因是什么呢?

英文:

I'm using Jackson with Kotlin binding in my project. We have a data class that has a field of type Map&lt;A, B&gt; and is named "isRecommended". When Jackson serializes the data class, this field gets omitted in the resultant JSON string.

A simple test to reproduce the same behavior:

class FooKotlin {
    @Test
    fun testFoo() {
        println(jacksonObjectMapper().writeValueAsString(Foo1(true)))
        println(jacksonObjectMapper().writeValueAsString(Foo2(1)))
        println(jacksonObjectMapper().writeValueAsString(Foo3(&quot;true&quot;)))
    }
}

data class Foo1(val isFoo: Boolean)
data class Foo2(val isFoo: Int)
data class Foo3(val isFoo: String)

The console prints:

{&quot;foo&quot;:true}
{}
{}

When I decompile the Kotlin bytecode, the three classes seem to have almost identical content except for the type of the field. So what is the cause of this behavior of Jackson?

答案1

得分: 2

以下是您要翻译的内容:

正如 @chrsblck 所提到的,这与 jackson-module-kotlin 问题 #80 有关。

在版本 2.10.1 上,尽管序列化属性名称不同(不会移除前缀 "is"),但无法重现:

{&quot;isFoo&quot;:true}
{&quot;isFoo&quot;:1}
{&quot;isFoo&quot;:&quot;true&quot;}

在较早的版本中,可以通过 JsonProperty 注解来解决此问题:

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

从技术上讲,给非布尔属性命名为 "isSomething" 是不正确的,违反了 JavaBeans 规范。Jackson 依赖于 JavaBeans 约定,因此会感到困惑。

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

英文:

As mentioned by @chrsblck it is related to the jackson-module-kotlin issue #80

On the version 2.10.1 it's not reproducible, although serialized properties names are different (the "is" prefix is not removed):

{&quot;isFoo&quot;:true}
{&quot;isFoo&quot;:1}
{&quot;isFoo&quot;:&quot;true&quot;}

On the earlier versions, the issue can be fixed with a JsonProperty annotation:

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

Technically, naming a non-boolean property "isSomthing" is incorrect and violates JavaBeans specification. Jackson relies on the JavaBeans conventions, thus it gets confused.

If you can avoid such naming, I would advise doing so. Otherwise, you may face the same problems when calling the Foo* classes from Java code.

huangapple
  • 本文由 发表于 2020年1月6日 15:50:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/59608443.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定