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反序列化多态类型(根据标识解析为子类对象

当然,我可以为您提供一个Java使用Jackson实现多态解析JSON的示例。这里是一个基本的示例代码: ``` public class Animal { public String name; public String type; } @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 AnimalMixin { @JsonCreator public AnimalMixin(@JsonProperty("name") String name) { } } public class Dog extends Animal { public String breed; public Dog() {} public Dog(String name, String breed) { this.name = name; this.breed = breed; this.type = "dog"; } } public class Cat extends Animal { public int age; public Cat() {} public Cat(String name, int age) { this.name = name; this.age = age; this.type = "cat"; } } public static void main(String[] args) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); String json = "{ \"name\": \"Fido\", \"type\": \"dog\", \"breed\": \"beagle\" }"; Animal animal = mapper.readValue(json, Animal.class); System.out.println(animal.name); System.out.println(((Dog)animal).breed); } ``` 在这个示例中,我们有一个Animal类,它有一个name属性一个type属性。type属性用于标识动物的类型,它将在JSON解析期间用于决定将JSON转换为哪个子类。我们通过@JsonTypeInfo注释@JsonSubTypes注释来指示Jackson使用多态解析JSON。@JsonTypeInfo注释告诉Jackson使用"type"属性来确定JSON应该被反序列化为哪个类。@JsonSubTypes注释告诉Jackson哪些子类需要被考虑。 我们还有一个AnimalMixin抽象类,它用于处理将JSON转换为适当的子类。在这个例子中,我们有两个实现:DogCat。两个类都有它们自己的属性,但都继承自Animal类。 在main方法中,我们首先创建一个ObjectMapper对象,然后使用readValue方法将JSON字符串转换为Animal对象。然后我们打印了Animal对象的name属性子类特有的属性。 这是一个Java使用Jackson实现多态解析JSON的基本示例。我希望它能帮助您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值