Как контролировать нулевую десериализацию со значениями по умолчанию и необходимыми значениями в Джексоне с Kotlin? - PullRequest
0 голосов
/ 03 октября 2018

Использование Jackson 2.9.6

У меня есть следующее определение класса данных:

data class SomeDTO @JsonCreator internal constructor
(
    @get:JsonProperty(value = "first-property", required = true)
    @param:JsonProperty(value = "first-property", required = true)
    val firstProperty: Long?,

    @get:JsonProperty(value = "second-property")
    @param:JsonProperty(value = "second-property")
    val secondProperty: Int = 1234

    @get:JsonProperty("third-property", required = true)
    @param:JsonProperty("third-property", required = true)
    val thirdProperty: Int
)

Что я ожидаю от JSON, который десериализуется в SomeDTO

  1. Если firstProperty отсутствует, должно выдаться исключение.
  2. Если firstProperty имеет значение null, ему следует присвоить значение null, поскольку оно может иметь значение null.
  3. Если secondProperty отсутствует или равен нулю, ему следует присвоить значение по умолчанию 1234
  4. Если thirdProperty отсутствует или равно нулю, должно выдаться исключение.

По сути, я могу контролировать, какие значения можно десериализовать и во что.

Что я испытываю:

Если не с использованием KotlinModule, тогда (1), (2) и (4) работают, но (3) не работают с:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Невозможно отобразитьnull для типа int (установите для DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES значение 'false', чтобы разрешить)

Если вы используете KotlinModule, то (2), (3) и (4) работают, но (1)не удается.

Основная часть конфигурации ObjectMapper:

disable(
        MapperFeature.AUTO_DETECT_CREATORS,
        MapperFeature.AUTO_DETECT_FIELDS,
        MapperFeature.AUTO_DETECT_GETTERS,
        MapperFeature.AUTO_DETECT_IS_GETTERS
       )
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)

registerModule(ParanamerModule())
registerModule(KotlinModule()) // Might be registered or not

disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)

Я думаю, что проще использовать KotlinModule, но я не знаю, как сказать, что нетавтоматическое присвоение пустых значений пустым полям, когда свойство отсутствует в JSON

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Обновление модуля Kotlin до версии 2.9.7 приводит к исключению, когда firstProperty отсутствует.Я неоднократно проверял это, переходя между 2.9.6 и 2.9.7 с кодом и конфигурацией, скопированной из OP.

Исправление ошибки в 2.9.7 соответствует неожиданному поведению, описанному в OP.

Исправления # 168, где JsonProperty(required=true) игнорировался и переопределялся проверкой обнуляемости

https://github.com/FasterXML/jackson-module-kotlin/issues/168

0 голосов
/ 03 октября 2018

Это должно делать то, что вы хотите:

data class SomeDTO(
        @JsonProperty(value = "first-property", required = true)
        val firstProperty: Long?,

        @JsonProperty(value = "second-property")
        val secondProperty: Int = 1234,

        @JsonProperty("third-property", required = true)
        val thirdProperty: Int
)

Несколько замечаний:

1.Поскольку вы используете основной конструктор для своих аннотированных полей, в Kotlin вам не нужна аннотация @JsonCreator.

Это то, что GitHub-страница проекта Джексона говорит:

По умолчанию Джексон пытается использовать конструктор «по умолчанию» (без аргументов) при создании экземпляров значений.Но вы также можете использовать другой конструктор или статический метод фабрики для создания экземпляра.Для этого вам нужно будет использовать аннотацию @JsonCreator и, возможно, аннотации @JsonProperty для привязки имен к аргументам

Вам не нужны отдельные аннотации @get и @param.@JsonProperty достаточно для вашего варианта использования.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...