Bootstrap

Jackson 中的多态类型支持:@JsonTypeInfo 和 @JsonSubTypes 使用技巧

概要

@JsonTypeInfo@JsonSubTypes 是 Jackson 库中用于处理多态类型的注解。它们的作用是在序列化和反序列化过程中,帮助 Jackson 识别和处理父类与子类之间的关系。

@JsonTypeInfo 注解

@JsonTypeInfo 注解用于指定在序列化和反序列化过程中如何处理类型信息。

参数说明:

  • use:指定类型信息的标识方式。常用的选项有:

    • JsonTypeInfo.Id.NAME:使用名称(字符串)来标识类型。
    • JsonTypeInfo.Id.CLASS:使用类的全限定名来标识类型。
    • JsonTypeInfo.Id.MINIMAL_CLASS:使用类的最小化名称来标识类型。
    • JsonTypeInfo.Id.CUSTOM:自定义类型标识方式。
  • include:指定类型信息如何包含在 JSON 中。常用的选项有:

    • JsonTypeInfo.As.PROPERTY:将类型信息作为一个单独的属性(字段)包含在 JSON 中。
    • JsonTypeInfo.As.WRAPPER_OBJECT:将类型信息包装在一个外部对象中。
    • JsonTypeInfo.As.WRAPPER_ARRAY:将类型信息包装在一个数组中。
    • JsonTypeInfo.As.EXISTING_PROPERTY:使用现有的属性来存储类型信息。
  • property:当 includeJsonTypeInfo.As.PROPERTY 时,指定类型信息属性的名称。例如,property = "type" 表示在 JSON 中添加一个名为 type 的字段来存储类型信息。


@JsonSubTypes 注解

@JsonSubTypes 注解用于列出所有可能的子类类型,并为每个子类指定一个唯一的名称(或标识符)。

参数说明:

  • value:一个 @JsonSubTypes.Type 注解数组,每个 @JsonSubTypes.Type 注解表示一个子类。
  • @JsonSubTypes.Type:用于指定子类的类型和名称。
    • value:子类的 Class 对象。
    • name:子类的唯一标识符(字符串),用于在 JSON 中标识该子类。

示例

jackson 坐标:(三个依赖保持版本一致)

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.14.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.14.2</version>
</dependency>

java 示例代码

@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")
})
@Data
abstract class Animal {
    private String name;
}

@Data
class Dog extends Animal {
    private String breed;
}

@Data
class Cat extends Animal {
    private String color;
}

@Data
class Zoo {
    private List<Animal> animals;
}

public class Main {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        Zoo zoo = new Zoo();
        List<Animal> animals = new ArrayList<>();
        zoo.setAnimals(animals);

        Dog dog = new Dog();
        dog.setName("Buddy");
        dog.setBreed("Golden Retriever");
        animals.add(dog);

        Cat cat = new Cat();
        cat.setName("Whiskers");
        cat.setColor("Black");
        animals.add(cat);

        // 序列化
        String zooJson = mapper.writeValueAsString(zoo);
        System.out.println(zooJson);

        // 反序列化
        Zoo parsedZoo = mapper.readValue(zooJson, Zoo.class);
        System.out.println(parsedZoo);
    }
}

结果:

{"animals":[{"type":"dog","name":"Buddy","breed":"Golden Retriever"},{"type":"cat","name":"Whiskers","color":"Black"}]}
Zoo(animals=[Dog(breed=Golden Retriever), Cat(color=Black)])

参考地址:Jackson使用@JsonTypelnfo反序列化多态类型(根据标识解析为子类对象

;