官方WIKI:https://github.com/FasterXML/jackson-databind/wiki
jackson 1.x和2.x版本的注解是放置在不同的包下的
1.x是在jackson core jar包org.codehaus.jackson.annotate下
2.x是在jackson-databind包com.fasterxml.jackson.annotation下
jackson的自动检测机制
jackson允许使用任意的构造方法或工厂方法来构造实例
fieldVisibility:字段的可见级别
ANY:任何级别的字段都可以自动识别
NONE:所有字段都不可以自动识别
NON_PRIVATE:非private修饰的字段可以自动识别
PROTECTED_AND_PUBLIC:被protected和public修饰的字段可以被自动识别
PUBLIC_ONLY:只有被public修饰的字段才可以被自动识别
DEFAULT:同PUBLIC_ONLY
jackson默认的字段属性发现规则如下:
所有被public修饰的字段->所有被public修饰的getter->所有被public修饰的setter
举例:
- public static class TestPOJO{
- TestPOJO(){}
-
- TestPOJO(String name){
- this.name = name;
- }
- private String name;
-
- @Override
- public String toString() {
- return "TestPOJO{" +
- "name='" + name + '\'' +
- '}';
- }
- }
这个类我们只有一个private的name属性,并且没有提供对应的get,set方法,如果按照默认的属性发现规则我们将无法序列化和反序列化name字段(如果没有get,set方法,只有被public修饰的属性才会被发现),你可以通过修改@JsonAutoDetect的fieldVisibility来调整自动发现级别,为了使name被自动发现,我们需要将级别调整为ANY
- @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
同理,除了fieldVisibility可以设置外,还可以设置getterVisibility、setterVisibility、isGetterVisibility、creatorVisibility级别,不再多讲
除了上面的方式,你还可以有一些其他方式可以配置methods,fields和creators(构造器和静态方法)的自动检测,例如:
你可以配置MapperFeature来启动/禁止一些特别类型(getters,setters,fields,creators)的自动检测
比如下面的MapperFeature配置:
SORT_PROPERTIES_ALPHABETICALLY:按字母顺序排序属性
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true);
一些我们比较常用的SerializationFeature配置:
SerializationFeature.WRAP_ROOT_VALUE:是否环绕根元素,默认false,如果为true,则默认以类名作为根元素,你也可以通过@JsonRootName来自定义根元素名称
- objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE,true);
举例:
- @JsonRootName("myPojo")
- public static class TestPOJO{
- private String name;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
该类在序列化成json后类似如下:{"myPojo":{"name":"aaaa"}}
SerializationFeature.INDENT_OUTPUT:是否缩放排列输出,默认false,有些场合为了便于排版阅读则需要对输出做缩放排列
- objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
举例:
如果一个类中有a、b、c、d四个可检测到的属性,那么序列化后的json输出类似下面:
{
"a" : "aaa",
"b" : "bbb",
"c" : "ccc",
"d" : "ddd"
}
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS:序列化日期时以timestamps输出,默认true
- objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,true);
比如如果一个类中有private Date date;这种日期属性,序列化后为:{"date" : 1413800730456},若不为true,则为{"date" : "2014-10-20T10:26:06.604+0000"}
SerializationFeature.WRITE_ENUMS_USING_TO_STRING:序列化枚举是以toString()来输出,默认false,即默认以name()来输出
- objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);
SerializationFeature.WRITE_ENUMS_USING_INDEX:序列化枚举是以ordinal()来输出,默认false
- objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,true);
举例:
- @Test
- public void enumTest() throws Exception {
- TestPOJO testPOJO = new TestPOJO();
- testPOJO.setName("myName");
- testPOJO.setMyEnum(TestEnum.ENUM01);
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,false);
- objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,false);
- String jsonStr1 = objectMapper.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"myEnum\":\"ENUM01\",\"name\":\"myName\"}",jsonStr1);
-
- ObjectMapper objectMapper2 = new ObjectMapper();
- objectMapper2.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);
- String jsonStr2 = objectMapper2.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"myEnum\":\"enum_01\",\"name\":\"myName\"}",jsonStr2);
-
- ObjectMapper objectMapper3 = new ObjectMapper();
- objectMapper3.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,true);
- String jsonStr3 = objectMapper3.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"myEnum\":0,\"name\":\"myName\"}",jsonStr3);
- }
- public static class TestPOJO{
- TestPOJO(){}
- private TestEnum myEnum;
- private String name;
-
-
- }
-
- public static enum TestEnum{
- ENUM01("enum_01"),ENUM02("enum_01"),ENUM03("enum_01");
-
- private String title;
-
- TestEnum(String title) {
- this.title = title;
- }
-
- @Override
- public String toString() {
- return title;
- }
- }
SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED:序列化单元素数组时不以数组来输出,默认false
- objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);
举例:
- @Test
- public void singleElemArraysUnwrap() throws Exception {
- TestPOJO testPOJO = new TestPOJO();
- testPOJO.setName("myName");
- List<Integer> counts = new ArrayList<>();
- counts.add(1);
- testPOJO.setCounts(counts);
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,false);
- String jsonStr1 = objectMapper.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"counts\":[1]}",jsonStr1);
-
- ObjectMapper objectMapper2 = new ObjectMapper();
- objectMapper2.configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,true);
- String jsonStr2 = objectMapper2.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"counts\":1}",jsonStr2);
- }
-
- public static class TestPOJO{
- private String name;
- private List<Integer> counts;
-
-
- }
SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS:序列化Map时对key进行排序操作,默认false
- objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,true);
举例:
- @Test
- public void orderMapBykey() throws Exception {
- TestPOJO testPOJO = new TestPOJO();
- testPOJO.setName("myName");
- Map<String,Integer> counts = new HashMap<>();
- counts.put("a",1);
- counts.put("d",4);
- counts.put("c",3);
- counts.put("b",2);
- counts.put("e",5);
- testPOJO.setCounts(counts);
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,false);
- String jsonStr1 = objectMapper.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"counts\":{\"d\":4,\"e\":5,\"b\":2,\"c\":3,\"a\":1}}",jsonStr1);
-
- ObjectMapper objectMapper2 = new ObjectMapper();
- objectMapper2.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,true);
- String jsonStr2 = objectMapper2.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"counts\":{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}}",jsonStr2);
- }
-
- public static class TestPOJO{
- private String name;
- private Map<String,Integer> counts;
-
-
- }
SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS:序列化char[]时以json数组输出,默认false
- objectMapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,true);
举例:
- @Test
- public void charArraysAsJsonArrays() throws Exception {
- TestPOJO testPOJO = new TestPOJO();
- testPOJO.setName("myName");
- char[] counts = new char[]{
'a','b','c','d'};
- testPOJO.setCounts(counts);
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,false);
- String jsonStr1 = objectMapper.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"counts\":\"abcd\"}",jsonStr1);
-
- ObjectMapper objectMapper2 = new ObjectMapper();
- objectMapper2.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,true);
- String jsonStr2 = objectMapper2.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"counts\":[\"a\",\"b\",\"c\",\"d\"]}",jsonStr2);
- }
-
- public static class TestPOJO{
- private String name;
- private char[] counts;
-
-
- }
SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN:序列化BigDecimal时之间输出原始数字还是科学计数,默认false,即是否以toPlainString()科学计数方式来输出
- objectMapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,true);
举例:
- @Test
- public void bigDecimalAsPlain() throws Exception {
- TestPOJO testPOJO = new TestPOJO();
- testPOJO.setName("myName");
- testPOJO.setCount(new BigDecimal("1e20"));
-
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN,false);
- String jsonStr1 = objectMapper.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"count\":1E+20}",jsonStr1);
-
- ObjectMapper objectMapper2 = new ObjectMapper();
- objectMapper2.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN,true);
- String jsonStr2 = objectMapper2.writeValueAsString(testPOJO);
- Assert.assertEquals("{\"name\":\"myName\",\"count\":100000000000000000000}",jsonStr2);
- }
更多的序列化配置参见
点击打开链接
配置DeserializationFeature
反序列化的配置这里不再多做解释,参见点击打开链接
需要注意的是对于第二种通过配置SerializationConfig和DeserializationConfig方式只能启动/禁止自动检测,无法修改我们所需的可见级别
有时候对每个实例进行可见级别的注解可能会非常麻烦,这时候我们需要配置一个全局的可见级别,通过objectMapper.setVisibilityChecker()来实现,默认的VisibilityChecker实现类为VisibilityChecker.Std,这样可以满足实现复杂场景下的基础配置。
也有一些实用简单的可见级别配置,比如:
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
- .setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)