Джексон игнорирует поля класса данных, которые не являются логическими, но имеют имена, начинающиеся с «is» - PullRequest
1 голос
/ 06 января 2020

Я использую Джексона с Kotlin привязкой в моем проекте. У нас есть класс данных, который имеет поле типа Map<A, B> и называется «isRecommended». Когда Джексон сериализует класс данных, это поле пропускается в результирующей строке 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, кажется, что три класса имеют почти идентичное содержимое, за исключением типа поля. Так в чем же причина такого поведения Джексона?

1 Ответ

2 голосов
/ 06 января 2020

Как упомянуто @chrsblck, оно связано с jackson-module- 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, поэтому он запутывается.

Если вы можете избежать такого именования, я бы посоветовал сделать это. В противном случае вы можете столкнуться с такими же проблемами при вызове классов Foo * из Java кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...