0%

Jackson 支持 Optional 类型字段

默认情况下,输入类对象中包含 Optional 类型字段,Json 序列化和反序列化都会有一些问题:

Optional 类型序列化 Json

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Book {
String title;
Optional<String> subTitle;
}

Book book = new Book();
book.setTitle("Oliver Twist");
book.setSubTitle(Optional.of("The Parish Boy's Progress"));

String result = mapper.writeValueAsString(book);

// 输出:
{"title":"Oliver Twist","subTitle":{"present":true}}

Json 序列化后,subTitle 字段并没有包含值, 而是一个嵌套的对象。

原因是 isPresent() 是一个 Optional 类的公共 getter 属性,在序列化时被直接序列化了。

Optional 类型反序列化 Json

对 Json 字符串反序列化成包含 Optional 字段的类会抛出 JsonMappingException 异常:

1
2
String bookJson = "{ \"title\": \"Oliver Twist\", \"subTitle\": \"foo\" }";
Book result = mapper.readValue(bookJson, Book.class);

解决方法

引入 jackson-datatype-jdk8 包依赖:

1
2
3
4
5
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.9.6</version>
</dependency>

在初始化 ObjectMapper 时,注册 Jdk8Module 模块:

1
2
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());