准备工作
准备一个Person类,用于后续测试。
public class Person {
private String name;
private Integer age;
public Person(){}
public Person(String name, Integer age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
JsonTypeInfo作用
主要用于将Java Class 以指定的格式序列化到Json字符串中,反序列化时就不需要显示的指定转换类型了。
测试代码
WRAPPER_ARRAY
以数组的方式,Class Type 为第一个元素,Json字符串为第二个元素。
序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
Person person = new Person("kleven", 18);
System.out.println(mapper.writeValueAsString(person));
}
结果:
[
"info.kleven.******.Person",
{
"name": "kleven",
"age": 18
}
]
反序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
String jsonString = "[\"info.kleven.******.Person\",{\"name\":\"kleven\",\"age\":18}]";
Person person = (Person) mapper.readValue(jsonString, Object.class);
System.out.println(person);
}
结果:
Person{name='kleven', age=18}
WRAPPER_OBJECT
以对象的形式,Class Type 为key, Json字符串为value。
序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT);
Person person = new Person("kleven", 18);
System.out.println(mapper.writeValueAsString(person));
}
结果:
{
"info.kleven.******.Person": {
"name": "kleven",
"age": 18
}
}
反序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT);
String jsonString = "{\"info.kleven.******.Person\":{\"name\":\"kleven\",\"age\":18}}";
Person person = (Person) mapper.readValue(jsonString, Object.class);
System.out.println(person);
}
结果:
Person{name='kleven', age=18}
PROPERTY
以属性的的方式,在Json字符串中体现为:"@class"为key,Class Type 为value。
序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
Person person = new Person("kleven", 18);
System.out.println(mapper.writeValueAsString(person));
}
结果:
{
"@class": "info.kleven.******.Person",
"name": "kleven",
"age": 18
}
反序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
String jsonString = "{\"@class\":\"info.kleven.******.Person\",\"name\":\"kleven\",\"age\":18}";
Person person = (Person) mapper.readValue(jsonString, Object.class);
System.out.println(person);
}
结果:
Person{name='kleven', age=18}
EXTERNAL_PROPERTY
序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.EXTERNAL_PROPERTY);
Person person = new Person("kleven", 18);
System.out.println(mapper.writeValueAsString(person));
}
结果:
直接报错。 阅读源码可知 2.5版本之后已经不支持EXTERNAL_PROPERTY 了。
EXISTING_PROPERTY
序列化后的字符串不包含Class Type。
序列化
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.EXISTING_PROPERTY);
Person person = new Person("kleven", 18);
System.out.println(mapper.writeValueAsString(person));
}
结果:
{
"name": "kleven",
"age": 18
}
反序列化
反序列化时需要显示指定读取的Java Class 类型。
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
String jsonString = "{\"name\":\"kleven\",\"age\":18}";
Person person = mapper.readValue(jsonString, Person.class);
System.out.println(person);
}
结果:
Person{name='kleven', age=18}
结论
- 如果是作为api返回结果,不需要反序列化时:不设置activateDefaultTyping或者使用EXISTING_PROPERTY。
- 如果作为缓存等,需要反序列化时:一般使用 WRAPPER_ARRAY、WRAPPER_OBJECT、PROPERTY中的一种。如果不指定则默认使用的是WRAPPER_ARRAY。