【问题标题】:Spring @RequestBody and Jackson custom polymorphic deserializationSpring @RequestBody 和 Jackson 自定义多态反序列化
【发布时间】:2021-12-20 08:40:01
【问题描述】:

假设我有一些带有@PostMapping 的@RestController,如下所示:

@PostMapping
public SomeResponse create(@RequestBody AbstractRequest request) {
    ...
}

而这个AbstractRequest 是一个由ConcreteOneRequestConcreteTwoRequest 类扩展的抽象类:

@Value
@SuperBuilder
public ConcreteOneRequest extends AbstractRequest {
    String concreteOneUniqueField;
}

@Value
@SuperBuilder
public ConcreteTwoRequest extends AbstractRequest {
    String concreteTwoUniqueField;
}

基于上述结构,我如何使用@JsonTypeInfo 和/或@JsonSubTypes 和/或@JsonTypeResolver 反序列化为正确的具体类?

我已阅读 Jackson JavaDocs,但无法理解它们的用法,我还搜索了具体示例,但没有找到符合我要求的示例。

请帮忙,提前谢谢。

【问题讨论】:

    标签: java spring jackson polymorphism deserialization


    【解决方案1】:

    AbstractRequest 中,您将添加以下类级别注释:

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.EXISTING_PROPERTY,
            property = AbstractRequest.DISCRIMINATOR
    )
    @JsonSubTypes({
            @JsonSubTypes.Type(value = ConcreteOneRequest.class, name = FeeDefinitionType.Discriminator.TIERED),
            @JsonSubTypes.Type(value = ConcreteTwoRequest.class, name = FeeDefinitionType.Discriminator.STANDARD),
    })
    

    其中@JsonTypeInfo 定义了多态反序列化设置。这里,重要的部分是DISCRIMINATOR 属性,它将是一个位于AbstractRequest 中的字符串。

    它会告诉 Jackson 在 API 请求中查找此键,并根据其值反序列化不同的对象实例。

    您将为它定义一个 getter,以便子类可以提供它们的区别值。

    @JsonSubTypes 中,您指明了可能用于反序列化的子类型列表。

    这是一个完整的例子:

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.EXISTING_PROPERTY,
            property = AbstractRequest.DISCRIMINATOR
    )
    @JsonSubTypes({
            @JsonSubTypes.Type(value = ConcreteOneRequest.class, name = ConcreteOneRequest.getType()),
            @JsonSubTypes.Type(value = ConcreteTwoRequest.class, name = ConcreteTwoRequest.getType())
    })
    public abstract class AbstractRequest {
        public static final String DISCRIMINATOR = "type";
    
        abstract String getType();
    
    }
    

    所以当ConcreteOneRequestgetType() 上返回"CONCRETE_REQUEST_ONE" 时,当API 请求中的type 键具有此值时,Jackson 将尝试对其进行反序列化。

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 1970-01-01
      • 2017-08-10
      • 2021-11-07
      • 1970-01-01
      • 2023-04-10
      • 2016-02-13
      • 2011-04-12
      • 2013-01-18
      相关资源
      最近更新 更多