#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()
}
}
К сожалению, оба варианта немного подробны.