Я пытаюсь десериализовать некоторые JSON входные данные в Spring, однако они содержат динамический c подтип features , который будет либо CarFeatures
, либо MotorbikeFeatures
. Оба они основаны на абстрактном классе VehicleFeatures
.
Ниже приведена моя текущая реализация (с примерами), однако компилятору нужен конкретный тип. Конкретный тип неизвестен до тех пор, пока не будет выполнен запрос, и даже тогда компилятор не знает, какой объект создать. Как я могу динамически создать два противоположных объекта? Я бы предпочел не менять структуру моего API. Есть ли лучший подход к этому вопросу?
Пример запроса # 1 :
{ // Maps to Vehicle
"make": "Ford",
"model": "Mustang",
"type": "car"
"features": { // Maps to Car
"doors": 5,
"seats": 5
}
}
Пример запроса # 2 :
{ // Maps to Vehicle
"make": "Harley-Davidson",
"model": "XR750",
"type": "motorbike"
"features": { // Maps to Motorbike
"handlebars": true
"seats": 1
}
}
Данные Класс для сопоставления с :
data class Vehicle(
@field: @NotNull()
val make: String,
@field: @NotNull()
val model: String,
@field: @NotNull()
val type: String,
@field: JsonProperty("features")
val features: VehicleFeatures /* Needs to map to Car OR Motorbike */
)
abstract class VehicleFeatures
data class CarFeatures(
@field: NotNull()
val doors: Int,
@field: NotNull()
val seats: Int
): VehicleFeatures()
data class MotorbikeFeatures(
@field: NotNull()
val handlebars: Boolean,
@field: NotNull()
val seats: Int
): VehicleFeatures()
Контроллер :
@PostMapping(produces = [MediaType.APPLICATION_JSON_VALUE])
fun createVehicle(@Valid @RequestBody json) {
// If we've reached here, deserialisation has been successful!
println(json)
}
Токовый выход :
Resolved [org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.package.VehicleFeatures]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.package.VehicleFeatures` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (PushbackInputStream); line: 5, column: 13] (through reference chain: com.package.RequestExample["features"])]