java - 使用@JsonTypeInfo和@JsonSubTypes,反序列化没有基类和类型信息的具体子类的对象

标签 java spring-boot rest jackson polymorphism

使用@JsonTypeInfo@JsonSubTypes,是否可以在没有类型信息的情况下反序列化具体子类的对象?

假设我有一个抽象 Animal 类:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class, name = "Dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "Cat")
})
public abstract class Animal {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

和一个Dog子类:

public class Dog extends Animal {
    private String breed;

    public Dog() {
    }

    public Dog(String name, String breed) {
        setName(name);
        setBreed(breed);
    }

    public String getBreed() {
        return breed;
    }

    public void setBreed(String breed) {
        this.breed = breed;
    }
}

我知道我可以根据其父类实例化子类对象,如下所示:

{
    "type": "Dog",
    "name": "Jack",
    "breed": "shepherd"
}
Animal deserializedDog = objectMapper.readValue(dogJson, Animal.class);

但是,有时我想直接实例化子类对象而不使用父类:

{
    "name": "Jack",
    "breed": "shepherd"
}
Dog deserializedDog = objectMapper.readValue(dogJson, Dog.class);

子类对象将被发送到端点:

@PostMapping("/endpoint")
    public ResponseEntity<Dog> sendDataToJms(
            @RequestBody Dog request, @RequestHeader Map<String, String> headers) throws Exception {
    //...
}

可能吗?

最佳答案

我找到了解决办法。

您需要启用MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL,以便使用不带类型信息的具体子类直接反序列化对象。

根据官方文档,

MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL is a feature that specifies whether the declared base type of a polymorphic value is to be used as the "default" implementation, if no explicit default class is specified via @JsonTypeInfo.defaultImpl annotation.

接下来,您需要自定义 MappingJackson2HttpMessageConverter,将 JSON 请求转换为 Java 对象,如下所示。

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enable(MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL);
    jsonConverter.setObjectMapper(objectMapper);
    return jsonConverter;
}

关于java - 使用@JsonTypeInfo和@JsonSubTypes,反序列化没有基类和类型信息的具体子类的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66848837/

相关文章:

java - 为什么这个方法的时间复杂度是2*O(n log n) + O(m log m)?

mysql - Flyway 脚本因单个 schema 中的两个 schema_version 表而失败[已解决]

java - 如何获取每天随着天数递增的输出

java - 如果我们保持空闲一段时间,连接到 Azure MSSQL DB 时,Spring Boot 应用程序中的数据库连接会关闭

c# - HttpClient - 处理聚合异常

java - 我如何将一个 bean 合并到另一个 bean 中以进行部分更新

java - mapreduce 中线程 "main"java.io.IOException : Job failed! 中的异常

java - Spring Controller - 线程安全和存储资源

java - 如何将数组复制/添加到数组列表

node.js - Express 无法 PUT/DELETE 方法。出了什么问题?