• Jackson ObjectMapper activateDefaultTyping 中 JsonTypeInfo 的作用


    准备工作

    准备一个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 +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    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));
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:

    [
        "info.kleven.******.Person", 
        {
            "name": "kleven", 
            "age": 18
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    反序列化

        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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:

    Person{name='kleven', age=18}
    
    • 1

    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));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:

    {
        "info.kleven.******.Person": {
            "name": "kleven", 
            "age": 18
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    反序列化

        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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:

    Person{name='kleven', age=18}
    
    • 1

    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));
        }
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:

    {
        "@class": "info.kleven.******.Person", 
        "name": "kleven", 
        "age": 18
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    反序列化

        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);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:

    Person{name='kleven', age=18}
    
    • 1

    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));
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果:
    Jackson ObjectMapper activateDefaultTyping 代码示例
    直接报错。 阅读源码可知 2.5版本之后已经不支持EXTERNAL_PROPERTY 了。
    ObjectMapper 源码

    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));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:

    {
        "name": "kleven", 
        "age": 18
    }
    
    • 1
    • 2
    • 3
    • 4

    反序列化
    反序列化时需要显示指定读取的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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果:

    Person{name='kleven', age=18}
    
    • 1

    结论

    1. 如果是作为api返回结果,不需要反序列化时:不设置activateDefaultTyping或者使用EXISTING_PROPERTY。
    2. 如果作为缓存等,需要反序列化时:一般使用 WRAPPER_ARRAYWRAPPER_OBJECTPROPERTY中的一种。如果不指定则默认使用的是WRAPPER_ARRAY
      Jackson ObjectMapper activateDefaultTyping 中 JsonTypeInfo 的作用
  • 相关阅读:
    【使用python写代码 完成绘制词云】
    第二十章《Java Swing》第2节:窗体的创建
    模拟开关的认识与应用
    “元宇宙”最权威的解释来了!全国科技名词委研讨会达成共识
    公司大数据智能管理平台密码不正确 Hue平台进不去
    ASP.NET Core 8 的 Web App
    hive拼接字符串concat函数的用法
    Spring - Cloud (微服务)
    【JavaWeb】登陆页面
    Nokogiri库和OpenURI库使用HTTP做一个爬虫
  • 原文地址:https://blog.csdn.net/u012359704/article/details/126751253