Jackson 中的各种 Features
先来看看 jackson 中的各种feature
首先是 序列化时候的Feature ——
SerializaitonFeature
WRAP_ROOT_VALUE(false)
: 序列化的json是否显示根节点
1 | public static void testWrapRoot() { |
运行结果:
{"name":"TEST_WRAP_ROOT_VALUE","code":1,"desc":["test1","test2","test3"]}
去掉注释的运行结果:
{"SimpleBean":{"name":"TEST_WRAP_ROOT_VALUE","code":1,"desc":["test1","test2","test3"]}}
从结果可以看出 jackson 会把类名作为根节点展示
INDENT_OUTPUT(false)
: 允许或禁止是否以缩进的方式展示json
1 | public static void testIdentOutput() { |
输出的结果:
{
"name" : "TEST_WRAP_ROOT_VALUE",
"code" : 1,
"desc" : [ "test1", "test2", "test3" ]
}
FAIL_ON_EMPTY_BEANS
(true): 当类的一个属性外部无法访问(如:没有getter setter 的私有属性),且没有annotation 标明需要序列化时,如果FAIL_ON_EMPTY_BEANS 是true 将会跑出异常,如果是false 则不会跑出异常
1 | public static void testFailOnEmptyField() { |
代码运行结果
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class com.liam.learning.Main$TestBean and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:275)
at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1109)
at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1134)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3672)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3048)
at com.liam.learning.Main.testFailOnEmptyField(Main.java:56)
at com.liam.learning.Main.main(Main.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
取消注释的运行结果:
{}
FAIL_ON_SELF_REFERENCES(true)
如果POJO 中有一个直接自我引用,在序列化的时候会抛出 com.fasterxml.jackson.databind.JsonMappingException
WRAP_EXCEPTIONS(true)
如果序列化过程中,如果抛出 Exception 将会被包装,添加额外的上下文信息
FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS(true),
CLOSE_CLOSEABLE(false),
FLUSH_AFTER_WRITE_VALUE(true),
WRITE_DATES_AS_TIMESTAMPS(true),
WRITE_DATE_KEYS_AS_TIMESTAMPS(false),
WRITE_DATES_WITH_ZONE_ID(false),
WRITE_DURATIONS_AS_TIMESTAMPS(true),
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false): 序列化json 的时候对于 char[]
为true 则解析成数组形式; 为false 则解析成一个字符串(String)
示例代码
1 | private static void testWriteCharArraysAsJsonArrays() { |
运行结果如下:
"tester"
去掉注释后,运行结果如下
["t","e","s","t","e","r"]
WRITE_ENUMS_USING_TO_STRING(false): 序列化时, enable: 用枚举的 enum.toString() 表示枚举值 disable: 用枚举的 enum.name() 表示枚举值
1 | private static void testWriteEnumsUsingString() { |
代码运行结果:
"BOY"
去掉注释后的代码运行结果:
"+BOY+"
WRITE_ENUMS_USING_INDEX(false): 序列化时,用枚举的 enum.index() 表示枚举值
1 | private static void testWriteEnumsUsingIndex() { |
代码运行结果:
"BOY"
取消注释后代码运行结果:
0
WRITE_NULL_MAP_VALUES(true): 对于 Map 中的 null 值 是否序列化
1 | public static void testWriteNullMapValues() { |
代码运行结果:
{"test1":null,"test2":"not null"}
去除注释后的运行结果:
{"test2":"not null"}
WRITE_EMPTY_JSON_ARRAYS(true): 对于空的 Collection
、 数组
; 为 true
则序列化, 为 false
则跳过, 默认为 true
示例代码:
1 | private static void testWriteEmptyJsonArrays() { |
运行结果如下:
{"name":"WRITE_EMPTY_JSON_ARRAYS","code":1,"desc":[],"ext":null}
取消注释后,运行结果如下:
{"name":"WRITE_EMPTY_JSON_ARRAYS","code":1,"ext":null}
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED(false): 序列化json时,对于只有单个元素的数组,不用中括号(‘[]’)括起来
1 | public static void testWrietSingleElemArraysUnwrapped() { |
代码运行结果:
{"name":"TEST_WRAP_ROOT_VALUE","code":1,"desc":["test1"]}
去掉注释之后的,运行结果
{"name":"TEST_WRAP_ROOT_VALUE","code":1,"desc":"test1"}
效果一目了然!
WRITE_BIGDECIMAL_AS_PLAIN(false): @deprecated
@see
com.fasterxml.jackson.core.JsonGenerator.Feature#WRITE_BIGDECIMAL_AS_PLAIN
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS(true): 序列化json的时候把时间类型值序列化成纳秒的形式
`注意` 只有最新版本(`jdk8` 中的 `Date/Time` )的时间类型支持本特性, `jdk8` 之前的 `java.util.Date` 和`joda-time` 都不支持!
ORDER_MAP_ENTRIES_BY_KEYS(false): 序列化 Map
的时候, 为 true
则按照 Map
的 key
进行排序,否则不排序
示例代码:
1 | private static void testOrderMapEntriesByKeys() { |
运行结果:
{"1":"test1","3":"test2","2":"test3","0":"test4"}
取消注释的运行结果:
{"0":"test4","1":"test1","2":"test3","3":"test2"}
EAGER_SERIALIZER_FETCH(true): 序列化是是否应当预先抓取必要的 JsonSerializer
, 绝大多数情况下不应该关闭此特性
USE_EQUALITY_FOR_OBJECT_ID(false)
;
接下来是 反序列化时候的Feature ——
DeserializationFeature
先来个最常用的: