如何基于jackson动态序列化指定字段

一、前言

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

二、序列化输出方式

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

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>

首先简单看下如何使用:

    @Data
    @JsonFilter("car")
    static class Car {
        private String brand;
        private long price;
        private int load;
        private long id;
    }


    @Data
    @JsonFilter("house")
    static class House {
        private String title;
        private long price;
        private long id;
    }


    @Data
    @JsonFilter("person")
    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,就可以做这个事件。

    @Data
    @JsonFilter("car")
    static class Car {
     ...
    }


    @Data
    @JsonFilter("house")
    static class House {
    ...
    }


    @Data
    @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注解,如果没有指定过滤器,则运行时会报错,那么如何让一个类即可以支持动态过滤,又在没指定过滤器的情况下正常运行那?其实很简单,我们可以自定义注解并注册解析器...

戳下面阅读

????

我的第三本书    我的第二本书    我的第一本书

golang并发教程    ForkJoinPool    K8s网络模型

人生需规划   再见阿里巴巴  我的视频号

点亮再看哦????

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Spring Boot 中,可以使用 Jackson 库来实现序列化动态修改字段名。下面是一种实现方式: 1. 首先,需要添加 Jackson 库的依赖。在 Maven 项目的 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> ``` 2. 创建一个自定义的序列化器,继承自 Jackson 库中的 JsonSerializer 类。在自定义序列化器中,重写 serialize() 方法来实现字段名的动态修改。 ```java import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; public class DynamicFieldNameSerializer extends JsonSerializer<String> { @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 根据需要修改字段名的逻辑,这里示例将字段名转为大写 String modifiedFieldName = value.toUpperCase(); gen.writeFieldName(modifiedFieldName); } } ``` 3. 在需要动态修改字段名的类的字段上使用 @JsonSerialize 注解,并指定自定义的序列化器。这样在序列化时,Jackson 库会调用自定义序列化器来处理字段名。 ```java import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.HashMap; import java.util.Map; public class MyObject { @JsonSerialize(using = DynamicFieldNameSerializer.class) private String fieldName; // Getter and Setter } ``` 4. 在 Spring Boot 的配置类中配置 Jackson 的 ObjectMapper,以注册自定义的序列化器。 ```java import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(String.class, new DynamicFieldNameSerializer()); objectMapper.registerModule(module); return objectMapper; } } ``` 这样,当使用 Spring Boot 序列化 MyObject 对象时,字段名会根据自定义的序列化器进行动态修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值