zoukankan      html  css  js  c++  java
  • 基于jackson动态序列化指定字段(独家披露)

    一、前言

    把对象序列化为json字符串输出的库很多,本文我们来看如何基于jackson动态控制哪些属性需要进行序列化。

    二、序列化输出方式

    对应使用Jackson,需要我们在pom文件中引入下面依赖:

    <dependency&gt;
        <groupId&gt;com.fasterxml.jackson.core</groupId&gt;
        <artifactId&gt;jackson-databind</artifactId&gt;
        <version&gt;2.11.1</version&gt;
    </dependency&gt;
    
    

    首先简单看下如何使用:

      @Data
        static class Car {
            private String brand;
            private long price;
            private int load;
            private long id;
        }
    
        @Data
        static class House {
            private String title;
            private long price;
            private long id;
        }
    
        @Data
        static class Person {
            private Car car;
            private House house;
            private long weight;
            private long id;
            private String name;
        }
    
       public static Person makePerson() {
            Person person = new Person();
            person.setName("加多");
            person.setWeight(150);
            person.setId(8888);
    
            House house = new House();
            house.setId(234);
            house.setTitle("杭州院子");
            house.setPrice(10000000);
            person.setHouse(house);
    
            Car car = new Car();
            car.setBrand("玛莎拉蒂");
            car.setId(123L);
            car.setLoad(3);
            car.setPrice(1000000);
            person.setCar(car);
    
            return person;
        }
    
        public static void main(String[] arg) throws JsonProcessingException {
            //1.造人
            Person person = makePerson();
    
            //2.序列化为json字符串并输出
            ObjectMapper objectMapper = new ObjectMapper();
            System.out.println(objectMapper.writeValueAsString(person));
        }
    
    

    如上代码1,创建了一个Person类,代码2创建ObjectMapper,并且调用其writeValueAsString方法,把Person对象序列化为字符串,然后打印输出,结果为:

    {
        "car":{
            "brand":"玛莎拉蒂",
            "price":1000000,
            "load":3,
            "id":123
        },
        "house":{
            "title":"杭州院子",
            "price":10000000,
            "id":234
        },
        "weight":150,
        "id":8888,
        "name":"加多"
    }
    
    
    

    如上Person中所有属性,包含其中Car中所有属性,House的所属性都输出了。

    如果我们不想序列化某个属性,比如不想序列化Person中的Car中的price属性,则我们只需要在Car类属性上加注解:@JsonIgnore

       @Data
        static class Car {
            private String brand;
            @JsonIgnore
            private long price;
         ...
        }
    
    

    同理如果不想要序列化Person中的car属性,在其上添加@JsonIgnore注解即可。

    对应上面情况,我们只能静态的使用@JsonIgnore注解来过滤不需要序列化的属性,那么有没有办法在运行时进行动态过滤不需要过滤的属性那?其实注解@JsonFilter,就可以做这个事件。

    @JsonFilter("car")
    static class Car {
     ...
    }
    
    @JsonFilter("house")
    static class House {
    ...
    }
    
    @JsonFilter("person")
    static class Person {
        ...
    }
    
    

    如上首先在所有类上加上对应的注解,然后通过下面代码添加过滤器:

     public static void main(String[] arg) throws JsonProcessingException {
            //1.造人
            Person person = makePerson();
    
            //2.序列化为json字符串并输出
            ObjectMapper objectMapper = new ObjectMapper();
            //2.1创建过滤器
            SimpleFilterProvider filterProvider = new SimpleFilterProvider();
            //2.1.1Person类的属性过滤器(只序列化car,house,name字段)
            filterProvider.addFilter("person", SimpleBeanPropertyFilter.filterOutAllExcept(Sets.newHashSet("car", "house", "name")));
            //2.1.2House类的属性过滤器(只序列化title,price字段)
            filterProvider.addFilter("house", SimpleBeanPropertyFilter.filterOutAllExcept(Sets.newHashSet("title", "price")));
            //2.1.3Car类的属性过滤器(只序列化brand字段)
            filterProvider.addFilter("car", SimpleBeanPropertyFilter.filterOutAllExcept(Sets.newHashSet("brand")));
    
            //2.2设置过滤器,并执行序列化
            objectMapper.setFilterProvider(filterProvider);
            System.out.println(objectMapper.writeValueAsString(person));
        }
    
    

    如上代码通过2.1.1-2.1.3为Person,House,Car添加了属性过滤器,只序列化指定的字段,然后代码2.2把过滤器设置到ObjectMapper对象里面,最后执行序列化,运行上面代码,输出如下:

    {
        "car":{
            "brand":"玛莎拉蒂"
        },
        "house":{
            "title":"杭州院子",
            "price":10000000
        },
        "name":"加多"
    }
    
    

    可知序列化时,只序列化了我们指定的字段。上面代码只是一个实例,在运行时,我们可以根据需要动态设置过滤器,来起到动态序列化指定字段的功能。

    三、总结

    本文我们谈论了如何使用@JsonFilter进行动态指定需要序列化字段的功能。需要注意的是一旦一个类上加了@JsonFilter注解,如果没有指定过滤器,则运行时会报错,那么如何让一个类即可以支持动态过滤,又在没指定过滤器的情况下正常运行那?其实很简单,我们可以自定义注解并注册…

  • 相关阅读:
    Java学习:面向对象三大特征:封装、继承、多态之封装性
    Java学习:构造方法
    Java学习:集合双列Map
    斗地主综合案例:有序版本(双列)
    JDK9对集合添加的优化
    Java学习:Debug调试程序
    计算一个字符串中每一个字符出现的次数
    Java学习:Map接口
    Java学习:可变参数
    Pediy CTF 2018 reverse
  • 原文地址:https://www.cnblogs.com/ming569/p/13720572.html
Copyright © 2011-2022 走看看