首页 > 解决方案 > 使用具体实现时 @JsonTypeInfo 对 REST 端点的影响

问题描述

我想知道将 a 添加@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即使我使用的是具体类,为什么还是预期的?这是预期的行为还是我做错了什么?

标签: springrestkotlinjacksonpolymorphism

解决方案


嗯,这是意料之中的,因为@JsonTypeInfo通过类接口继承对类进行注释,您已经明确指示您的杰克逊期待这些信息。

@JsonTypeInfo接受将使用defaultImpl的类型参数Class<?>

如果类型标识符不存在,或者不能映射到已注册的类型

您可以使用它将反序列化默认为一种类型的消息,最好是在您的 api 中显式使用最广泛的消息。对于其他类型,您仍然需要包含 Jackson 的课程信息。


推荐阅读