Jackson 中的多态类型支持:@JsonTypeInfo 和 @JsonSubTypes 使用技巧
文章目录
- 概要
- @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
:当include
为JsonTypeInfo.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反序列化多态类型(根据标识解析为子类对象