Jackson学习笔记(三)

Posted by lili on March 29, 2022

本文介绍常见的注解。

目录

JsonAnyGetter

我们有的时候不想(也不可能)定义所有的字段,因此可能把哪些可能动态增加的字段放到一个Map里:

public class BeanWithMap {
    public String name;
    public Map<String, String> properties = new HashMap<>();

    public BeanWithMap(String name){
        this.name = name;
    }

    public void addAttr(String k, String v){
        properties.put(k, v);
    }
}

但是这样序列化的结果就是会多出一个层次:

public class TestBeanWithMap {
    public static void main(String[] args) throws JsonProcessingException {
        BeanWithMap bean = new BeanWithMap("My bean");
        bean.addAttr("attr1", "val1");
        bean.addAttr("attr2", "val2");

        String result = new ObjectMapper().writeValueAsString(bean);
        System.out.println(result);
    }
}

输出:

{
  "name" : "My bean",
  "properties" : {
    "attr2" : "val2",
    "attr1" : "val1"
  }
}

但是我们其实可能希望的JSON是这样:

{
  "name" : "My bean",
  "attr2" : "val2",
  "attr1" : "val1"
}

这个时候我们就可以使用JsonAnyGetter注解。首先我们在Bean里增加注解:

public class ExtendableBean {
    public String name;
    private Map<String, String> properties = new HashMap<>();

    public ExtendableBean(String name){
        this.name = name;
    }

    public void addAttr(String k, String v){
        properties.put(k, v);
    }

    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }
}

首先我们把properties设置为private,避免它也被序列化,然后定义个getProperties方法(方法名不重要),它返回properties,并且增加了JsonAnyGetter注解。这个注解告诉Jackson,除了name这些public(或者getXXX)的字段外,还需要把JsonAnyGetter返回的Map也作为key和value对进行序列化。我们来看测试代码:

public class TestJsonAnyGetter {
    public static void main(String[] args) throws JsonProcessingException {
        ExtendableBean bean = new ExtendableBean("My bean");
        bean.addAttr("attr1", "val1");
        bean.addAttr("attr2", "val2");

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectWriter writer = objectMapper.writer(new DefaultPrettyPrinter());
        System.out.println(writer.writeValueAsString(bean));
    }
}

输出为:

{
  "name" : "My bean",
  "attr2" : "val2",
  "attr1" : "val1"
}