Влияние @JsonTypeInfo на конечные точки REST при использовании конкретных реализаций - PullRequest
1 голос
/ 28 февраля 2020

Меня интересует эффект добавления @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") в интерфейс.

Мой пример использования: у меня интерфейсное сообщение со многими подтипами. Я хочу иметь возможность десериализовать и сериализовать списки сообщений в одной конечной точке.

Мои классы:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
interface Message: Serializable

data class Message1(
    val name: String,
    val age: Int
)

data class Message2(
    val name: String,
    val nickName: String
)

И соответствующая конечная точка:

@RestController
class MessageController {

    @GetMapping("/messages")
    fun getEndpoints(): List<Message> {
        return listOf(
            Message1("Marco", 22),
            Message2("Polo", "Poli")
        )
    }
}

Пока все хорошо - но теперь я хочу другую конечную точку, которая использует один из явных классов и я получаю ошибку сериализации в моем тесте, что @class отсутствует - я не хочу отправлять это, когда я использую конкретный класс в любом случае.

@RestController
class MessageController {

    @PostMapping("/add1")
    fun add(@RequestBody content: Message1) {
        // do something
    }
}
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Missing type id when trying to resolve subtype of [simple type, class com.tractive.tap.message.request.RequestDataDTO]: missing type id property '@class'; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.tractive.tap.message.request.RequestDataDTO]: missing type id property '@class'
 at [Source: (PushbackInputStream); line: 1, column: 51]

Почему ожидается @class, хотя я использую конкретный класс? Это ожидаемое поведение или я делаю что-то не так?

1 Ответ

0 голосов
/ 28 февраля 2020

Что ж, это ожидаемо, потому что, пометив класс с помощью @JsonTypeInfo - через наследование интерфейса класса - вы явно дали указание своему Джексону ожидать эту информацию.

@JsonTypeInfo принимает параметр defaultImpl типа Class<?>, который будет использоваться

, если идентификатор типа отсутствует или не может быть сопоставлен с зарегистрированным типом

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

...