-
测试类
-
@Data public abstract class Animal { private String name; } public class Elephant extends Animal{ } public class Monkey extends Animal{ } Elephant elephant = new Elephant(); elephant.setName("大象精"); Monkey monkey = new Monkey(); monkey.setName("孙悟空"); ObjectMapper objectMapper = new ObjectMapper(); System.out.println(objectMapper.writeValueAsString(elephant)); System.out.println(objectMapper.writeValueAsString(monkey));
-
输出
{"name":"大象精"} {"name":"孙悟空"}
-
原理
-
jackson 会获取 field 对应的 get 方法方法名,比如 getxxx,然后进行将 get 进行截断,变成xxx,即为对应的key
-
注意大写转小写问题
- 为避免,在field上加
@JsonProperty
, 在get set
上加@JsonIgnore
- 为避免,在field上加
-
-
-
@JsonTypeInfo注解开启多态处理
-
使用
@class
作为限定名 -
@JsonTypeInfo( use=Id.CLASS ) public abstract class Animal { private String name; //忽略getter和setter } # 序列化 # {"@class":"com.tinylynn.springboot.json.type.Elephant","name":"大象精"} # {"@class":"com.tinylynn.springboot.json.type.Monkey","name":"孙悟空"}
-
JsonTypeInfo.Id.NAME, 默认添加@type属性(使用简写
@type
+简写类名作为限定名){"@type":"Elephant","name":"大象精"} {"@type":"Monkey","name":"孙悟空"}
-
JsonTypeInfo.As.WRAPPER_OBJECT:作为一个包装的对象 @JsonTypeInfo( use=Id.NAME, include=As.WRAPPER_OBJECT ) public abstract class Animal { //... } {"Elephant":{"name":"大象精"}} {"Monkey":{"name":"孙悟空"}}
作为包装对象
-
WRAPPER_ARRAY 作为数组 ["Elephant",{"name":"大象精"}] ["Monkey",{"name":"孙悟空"}]
作为数组
-
@Data public class Zoo { @JsonTypeInfo(use=Id.NAME,include=As.EXTERNAL_PROPERTY) # EXTERNAL_PROPERTY 把该变量作为本类的额外属性 private Animal animal; //动物园名称 private String name; } Zoo zoo = new Zoo(); zoo.setName("只有一只大象的动物园"); zoo.setAnimal(elephant); System.out.println(objectMapper.writeValueAsString(zoo)); # animal的额外属性"@type":"Elephant" {"animal":{"name":"大象精"},"@type":"Elephant","name":"只有一只大象的动物园"}
作为一个额外的属性,跟POJO同级,只能用于属性,如何作用于类则跟JsonTypeInfo.As.PROPERTY是相同效果
-
include=JsonTypeInfo.As.PROPERTY
- 作为POJO的属性出现(序列化后在POJO的属性位置,在一个大括号内)
- 默认
-
property = "type"
-
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME property = "type" )
@type换为type
-
-
include= JsonTypeInfo.As.EXISTING_PROPERTY + property="type"
-
@JsonTypeInfo( include= JsonTypeInfo.As.EXISTING_PROPERTY, property="type", use= JsonTypeInfo.Id.NAME ) @Data public abstract class Animal { private String name; private String type; } # 测试 Elephant elephant = new Elephant(); elephant.setName("大象精"); elephant.setType("ele"); Monkey monkey = new Monkey(); monkey.setName("孙悟空"); monkey.setType("mon"); System.out.println(objectMapper.writeValueAsString(elephant)); System.out.println(objectMapper.writeValueAsString(monkey)); #结果 {"name":"大象精","type":"ele"} {"name":"孙悟空","type":"mon"}
使用已有属性type作为序列化key
注意不可以为property=“name”, 序列化后反序列化主key不论如何都是type
-
-
visible
(可选):- 定义识别码在反序列化时是否保留(不管false或true都不影响序列化)。默认是false,表示Jackson可以将识别码识别为类型后就删除。
-
-
@JsonSubTypes 反序列化
-
使用默认@type,不设置name,使用默认匹配方法
-
# 基类 @JsonTypeInfo( use = JsonTypeInfo.Id.NAME ) @JsonSubTypes({ //设置对应子类的识别码值 @JsonSubTypes.Type(value = Monkey.class) , @JsonSubTypes.Type(value = Elephant.class) }) @Data public abstract class Animal { private String name; } # 子类 class Elephant extends Animal{ } class Monkey extends Animal{ } # 测试 Elephant elephant = new Elephant(); elephant.setName("大象精"); Monkey monkey = new Monkey(); monkey.setName("孙悟空"); ObjectMapper objectMapper = new ObjectMapper(); # 序列化 String elephonJson = objectMapper.writeValueAsString(elephant); String monkeyJson = objectMapper.writeValueAsString(monkey); System.out.println(objectMapper.writeValueAsString(elephonJson)); System.out.println(objectMapper.writeValueAsString(monkeyJson)); # 结果 "{\"@type\":\"大象\",\"name\":\"大象精\"}" "{\"@type\":\"猴子\",\"name\":\"孙悟空\"}" # 此处@type为JsonTypeInfo.Id.NAME所带属性 # 反序列化 Animal elephantFromJson = objectMapper.readValue(elephonJson, Animal.class); System.out.println(elephantFromJson instanceof Elephant); elephantFromJson.name = "大象精" # 结果 true # 根据@JsonSubTypes.Type(value = Elephant.class) type的类名比较
-
使用指定name匹配
include= JsonTypeInfo.As.EXISTING_PROPERTY + property + @JsonSubTypes.type.name
name匹配property的type对应的属性,同时value=elephant.class也匹配
@JsonTypeInfo( include= JsonTypeInfo.As.EXISTING_PROPERTY, property="type", use= JsonTypeInfo.Id.NAME, visible = true ) @JsonSubTypes({ //设置对应子类的识别码值 @JsonSubTypes.Type(value = Elephant.class, name = "ele") }) @Data public abstract class Animal { private String name; private String type; } # 测试序列化 Elephant elephant = new Elephant(); elephant.setName("大象精"); elephant.setType("ele"); ObjectMapper objectMapper = new ObjectMapper(); String elephonJson = objectMapper.writeValueAsString(elephant); # 结果 # {"name":"大象精","type":"ele"} # 测试反序列化 Elephant elephantFromJson = objectMapper.readValue(elephonJson, Elephant.class); System.out.println(elephantFromJson); # 结果 # Animal(name=大象精, type=ele)
-
Java Jackson 序列化与反序列化
最新推荐文章于 2024-08-29 19:35:40 发布