声明: 此文章内容大部分来自于 www.baeldung.com/jackson 此系列文章,个人在其基础上作了一点改动,原文在外网,翻译放到此处仅仅作为分享,如涉及版权问题,请联系我删除。
学习Jackson的原因
因为SpringBoot选用了Jackson序列化Json数据,因此为了日常开发过程中避免踩坑,还是需要花点时间认真学习一下的。
这篇文章主要是学习一下如何使用Jackson序列化和反序列化 Optional 类型的字段。
Jackson在最新版本(2.17.2)支持注册第三方扩展模块来扩展功能,Jackson默认是不支持序列化Optional类型的字段的,我们先看一下Jackson的默认行为。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.17.2</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
</dependencies>
public class OptionalFieldTest {
@Test
public void testSerializeOptionalField() throws Exception {
ObjectMapper mapper = new ObjectMapper();
OptionalField optionalField = new OptionalField();
optionalField.setName("Alice");
optionalField.setOptionalAge(Optional.of(25));
String jsonString = mapper.writeValueAsString(optionalField);
System.out.println(jsonString);
}
private static class OptionalField {
private String name;
private Optional<Integer> optionalAge;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Optional<Integer> getOptionalAge() {
return optionalAge;
}
public void setOptionalAge(Optional<Integer> optionalAge) {
this.optionalAge = optionalAge;
}
}
}
结果如下
反序列化也会报此异常,它会提示你引入 jackson-datatype-jdk8解决此问题,我们按其提示来试一下。 首先是新增一个依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.17.2</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>
然后修改一下测试用例
public class OptionalFieldTest {
@Test
public void testSerializeOptionalField() throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 注意下面这一行代码,注册Jdk8Module
mapper.registerModule(new Jdk8Module());
OptionalField optionalField = new OptionalField();
optionalField.setName("Alice");
optionalField.setOptionalAge(Optional.of(25));
String jsonString = mapper.writeValueAsString(optionalField);
System.out.println(jsonString);
}
private static class OptionalField {
private String name;
private Optional<Integer> optionalAge;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Optional<Integer> getOptionalAge() {
return optionalAge;
}
public void setOptionalAge(Optional<Integer> optionalAge) {
this.optionalAge = optionalAge;
}
}
}
其结果如下:
然后我们再验证一下反序列化
@Test
public void testDeserializeOptionalField() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
String jsonString = "{"name":"Alice","optionalAge":25}";
OptionalField optionalField = mapper.readValue(jsonString, OptionalField.class);
System.out.println(optionalField.getName());
System.out.println(optionalField.getOptionalAge().get());
}
结果如下
至此,已经知道如何实现序列化和反序列化Optional类型的字段了。