Привязка данных Jackson не устанавливает значение по умолчанию

#kotlin #jackson #quarkus

#kotlin #jackson #quarkus

Вопрос:

В моем приложении quarkus у меня есть конечная точка, которая принимает DTO, с полем, имеющим значение по умолчанию. Когда я не отправляю это поле, я все равно получаю исключение

 com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of
`FooDTO`, problem: Parameter specified as non-null is null: method
io.otherstuff.FooDTO.amp;<initamp;>, parameter someListVariable
at [Source: (io.quarkus.vertx.http.runtime.VertxInputStream); line: 4, column: 1]
  

Класс выглядит следующим образом:

 class FooDTO(
        override var someStringVar: String,
        override var someListVariable: List<Int> = emptyList(),
): BarDTO

---------------------------------------------

interface BarDTO {
    var someStringVar: String
    var someListVar: List<Int>
}

  

Теперь, если я отправлю полезную нагрузку, подобную этой

 {
    "someStringVar": "Hello Stackoverflow",
    "someListVar": []
}
  

это работает отлично, но когда я удаляю "someListVar" , я получаю исключение из приведенного выше, хотя оно должно просто инициализироваться как пустой список.
Любая помощь очень ценится!

Ответ №1:

Проблема в том, что во время обессоливания библиотека (fasterxml) вызывает основной конструктор с null: FooDTO("Hello Stackoverflow", null) . Вызов завершается исключением, поскольку someListVariable параметру не присваивается значение null (значение по умолчанию используется только тогда, когда paremeter вообще не предоставлен, а не когда оно равно null).

Одним из вариантов решения проблемы было бы предоставление явного JsonCreator:

 class FooDTO(
    override var someStringVar: String, 
    override var someListVariable: List<Int> = emptyList()) : BarDTO {

    companion object {
        @JvmStatic 
        @JsonCreator 
        fun of(
            @JsonProperty("someStringVar") someStringVar: String,
            @JsonProperty("someListVariable") someListVariable: List<Int>?) =
            FooDTO(someStringVar, someListVariable ?: emptyList())
    }
}
  

Другой возможностью является использование вторичного конструктора вместо значения по умолчанию:

 class FooDTO : BarDTO {

    override var someStringVar: String
    override var someListVariable: List<Int>

    @JsonCreator
    constructor(
        @JsonProperty("someStringVar") someStringVar: String,
        @JsonProperty("someListVariable") someListVariable: List<Int>?) {
        this.someStringVar = someStringVar
        this.someListVariable = someListVariable ?: emptyList()
    }
}
  

К сожалению, оба варианта немного подробны.