jackson 动态排除序列化字段

阅读:847
作者:majingjing
发布:2020-06-05 18:13:57

当我们在使用jackson来完成对象当序列化和反序列化当时候, 只需要在对象上加注解就可以轻松完成

springboot的@ResponseBody默认就是使用jackson来完成对象序列化的.

通过在对象上加注解虽然可以完成字段的过滤和自定义每次等, 但这个是全局但配置,

如果我们的项目在做逻辑处理的时候需要序列化部分字段到db, 而在response返回的时候缺只想返回部分内容, 此时就需要使用动态控制序列化字段手段来完成此功能.

不得不说jackson是真的强大, 相比fastjson最近接连爆出安全漏洞, 这款json操作十分灵活, 社区交流也很活跃.强烈推荐抛弃fastjson,拥抱jackson

业务场景描述:

有一个MyUser对象

public class MyUser {

    private String name;
    private String nickName;

	//@JsonIgnore
    private MyBook book;
    private MyComputer computer;

}
1 将 MyUser 对象转换成json, 发送给系统A
2 将MyUser 对象返回给客户端B , 但是book字段为隐私数据, 不能给客户端看,需要屏蔽掉

这个场景我们使用注解 @JsonIgnore , 那么系统A收到的数据也是没有 book 内容的,此时全局方案此处是无法胜任的.

解决方案

此时我们可以构建两个json解析对象 (ObjectMapper) , 一个Instance不做特殊处理, 一个Instance排除掉MyBook类型数据

代码示例

public class MyComputer {

    private String id;
    private int money;

    private MyBook book;

}
public class MyBook {

    private String name;
    private int count;

}

代码省略 get , set 方法

创建自定义注解 @IgnoreSchemaField
@JsonIgnoreType
public @interface IgnoreSchemaField {
}
jackson 配置
ObjectMapper objectMapper = null;
//objectMapper ... 初始化配置

//exclude MyBook
objectMapper.addMixIn(MyBook.class, IgnoreSchemaField.class);
测试代码
@Test
    public void serializer(){
        MyBook book=new MyBook();
        book.setName("java");
        book.setCount(2);

        MyComputer computer = new MyComputer();
        computer.setId("11");
        computer.setMoney(23);
        computer.setBook(book);

        MyUser user = new MyUser();
        user.setName("zhangsan");
        user.setNickName("zs");
        user.setBook(book);
        user.setComputer(computer);


        ObjectMapper objectMapper = null;
        //objectMapper ... 初始化配置

        //exclude MyBook
        objectMapper.addMixIn(MyBook.class, IgnoreSchemaField.class);

        String serialize = objectMapper.writeValueAsString(user);
        System.out.println(serialize);
    }
验证结果
{
  "name" : "zhangsan",
  "nick_name" : "zs",
  "computer" : {
    "id" : "11",
    "money" : 23
  }
}

如果注释掉 objectMapper.addMixIn(MyBook.class, IgnoreSchemaField.class); 这行代码

{
  "name" : "zhangsan",
  "nick_name" : "zs",
  "book" : {
    "name" : "java",
    "count" : 2
  },
  "computer" : {
    "id" : "11",
    "money" : 23,
    "book" : {
      "name" : "java",
      "count" : 2
    }
  }
}

Process finished with exit code 0

总结

通过自定义注解, 配置 addMixIn 来完成字段的特殊处理