网站首页 > 资源文章 正文
介绍
在本文中,我们会对 Optional 类进行一些说明,并且会解释下如果在使用 Optional 类的时候可能在 Jackson 中进行序列化和反序列化的过程中出现的问题。
针对上面的问题,本文会将会介绍在 Jackson 中如何处理 Optional 对象,和如果 Optional 对象可能出现潜在的 Null 的解决方案。
问题概览
首先让我们来看看如果使用 Jackson 来对 Optional 数据类型进行序列化和反序列化中出现的问题。
Maven 依赖
针对 Jackson,我们可以使用最新的版本。
当我们对本文进行更新的时候,jackson-core 的最新版本为 2.17.0。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
定义 Book 对象
随后让我们来定义一个 Book 对象,在 Book 对象中,我们有一个使用 Optional 的字段。
当然在这个 Book 对象中,我们还需要添加 Getter 和 Setter 方法,在文章中,我们就省略到这些方法了。
public class Book {
private String title;
private Optional<String> subTitle;
}
在的对数据对象进行初始化的时候,我们需要注意对 Optional 对象设置值的方式,因为不同的值会影响序列化和反序列化的情况。
序列化
让我们先来实例化 Book 这个对象:
Book book = new Book();
book.setTitle("Oliver Twist");
book.setSubTitle(Optional.of("The Parish Boy's Progress"));
随后,我们使用 Jackson 的 ObjectMapper 方法来对实例化后的对象进行序列化,我们使用下面的代码来进行序列化:
String result = mapper.writeValueAsString(book);
从输出的字段中,我们可以看到输出的字符串内容中并没有输出具体的值,而是输出为下面的内容:
{"title":"Oliver Twist","subTitle":{"present":true}}
尽管上面的输出看起来有点奇怪,但是上面的输出却是正确的情况,因为这个和 Optional 的特性是有关的。
方法 isPresent() Optional 的 public getter 方法,这就意味着在序列化的时候基于我们对象中存储的具体的值,Jackson 将会输出 True 或者 False 。
这是 Jackson 当前正确的输出方式。
但,我们可能考虑在输出的时候输出具体的值,至于怎么输出这个具体的值的方法,我们在后续的解决方案中提出。
反序列化
现在,让我们使用上面的代码来对对象数据进行反序列化,考察使用下面的代码:
@Test(expected = JsonMappingException.class)
public void givenFieldWithValue_whenDeserializing_thenThrowException
String bookJson = "{ \"title\": \"Oliver Twist\", \"subTitle\": \"foo\" }";
Book result = mapper.readValue(bookJson, Book.class);
}
当上面的代码运行的时候将会提示下面的错误信息:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.util.Optional` (no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value ('foo')
at [Source: (String)"{ "title": "Oliver Twist", "subTitle": "foo" }"; line: 1, column: 40] (through reference chain: com.ossez.jackson.optionalwithjackson.Book["subTitle"])
上面的错误信息针对 Jackson 来说是正确的,因为 Jackson 是需要一个构造方法来把 subtitle 参数的值来对 Optional 对象进行数据初始化。
解决方案
我们希望的是 Optional 对象应该把一个空的数据设置为 null,如果不是空的数据,Optional 应该使用值来进行处理。
针对上面的要求,Jackson 已经提供了解决方案,Jackson 针对 JDK8 的新增模块设置了一系列数据类型,这里就包括了 Optional。
Maven 依赖
首先,我们需要使用针对 JDK 8 使用的依赖,这个依赖的名称为:jackson-datatype-jdk8
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.17.0</version>
</dependency>
现在,我们需要把上面的依赖注册到 ObjectMapper:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
或者上面的 2 句话也可以简化成 1 句话:
ObjectMapper mapper = new ObjectMapper().registerModule(new Jdk8Module());
序列化
现在,让我们来进行测试。
让我们再次使用上面的代码来对 Book 这个对象进行序列化和反序列化,然后我们在对输出的字符串进行查看。
Book book = new Book();
book.setTitle("Oliver Twist");
book.setSubTitle(Optional.of("The Parish Boy's Progress"));
String serializedBook = mapper.writeValueAsString(book);
assertThat(from(serializedBook).getString("subTitle"))
.isEqualTo("The Parish Boy's Progress");
如果我们尝试序列化一个空的 Book 对象的话,那么 Optional 字段中存储的数据为 null。
book.setSubTitle(Optional.empty());
String serializedBook = mapper.writeValueAsString(book);
assertThat(from(serializedBook).getString("subTitle")).isNull();
##反序列化
现在我们来进行反序列化,当我们进行反序列化的时候,我们可以看到上面的代码不再抛出 JsonMappingException 异常。
Book newBook = mapper.readValue(result, Book.class);
assertThat(newBook.getSubTitle()).isEqualTo(Optional.of("The Parish Boy's Progress"));
最后,我们再对上面的测试代码进行测试,从上面的代码代码输出中我们也可以看到没有异常,同时我们还得到了一个空的 Optional 对象。
assertThat(newBook.getSubTitle()).isEqualTo(Optional.empty());
结论
本文对针对 JDK 8 的新特性中提供的一些数据模型进行一些说明。
Jackson 需要注册一个新的 jdk8 数据类型才能对数据进行处理。
因为 Optional 是 JDK 8 中提供的新的数据特性,因此我们对一些新的数据类型我们需要有一些了解。
同时,针对 Jackson 还是有必要保持 JDK 的版本一致性和尽量使用比较高的版本,这样就可以使用更多有关 Jackson 提供的功能。
猜你喜欢
- 2024-10-28 java新特性之Optional类介绍,解决空指针问题的终极类
- 2024-10-28 Jdk14都要出了,还不能使用 Optional优雅的处理空指针?
- 2024-10-28 「Java8」 你有正确的使用 Optional吗?
- 2024-10-28 深入探讨 Pydantic 中的 Optional 和 Union 类型
- 2024-10-28 漫画:你居然不知道 Maven 中 Optional 和 Exclusions 的区别?
- 2024-10-28 Java8-关于Optional的那些事(关于java application)
- 2024-10-28 还在重复写空指针检查代码?考虑使用 Optional 吧
- 2024-10-28 jdk8的optional深入详解(jdk8 document)
- 2024-10-28 Java 中的 Optional(java optional.of)
- 2024-10-28 吃透 JAVA8 -- Optional 特性全部用法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 电脑显示器花屏 (79)
- 403 forbidden (65)
- linux怎么查看系统版本 (54)
- 补码运算 (63)
- 缓存服务器 (61)
- 定时重启 (59)
- plsql developer (73)
- 对话框打开时命令无法执行 (61)
- excel数据透视表 (72)
- oracle认证 (56)
- 网页不能复制 (84)
- photoshop外挂滤镜 (58)
- 网页无法复制粘贴 (55)
- vmware workstation 7 1 3 (78)
- jdk 64位下载 (65)
- phpstudy 2013 (66)
- 卡通形象生成 (55)
- psd模板免费下载 (67)
- shift (58)
- localhost打不开 (58)
- 检测代理服务器设置 (55)
- frequency (66)
- indesign教程 (55)
- 运行命令大全 (61)
- ping exe (64)
本文暂时没有评论,来添加一个吧(●'◡'●)