广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Jackson处理Optional时遇到问题的解决与分析
  • 298
分享到

Jackson处理Optional时遇到问题的解决与分析

2024-04-02 19:04:59 298人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录前言目录正文1. 序列化Optional类型的问题2. 原因分析3. 解决办法总结前言 Optional是Java8中增加的一个特性,它的出现是为了解决Java中的空指针问题,相

前言

Optional是Java8中增加的一个特性,它的出现是为了解决Java中的空指针问题,相关介绍可以参考这篇 Java8中的Optional操作;

但是在Jackson中操作Optional类型的属性时,会遇到一些问题,比如序列化的数据不符合预期等;

下面就来介绍下遇到的问题以及如何解决;

目录

  • 序列化Optional类型的问题
  • 原因分析
  • 解决办法

正文

1. 序列化Optional类型的问题

其他类型的属性序列化时基本没啥问题,都会根据对象的值进行序列化;

但是Optional比较特殊,序列化时会输出present:true这样的数据;

下面我们看下例子;

这是User对象,其中nickname为Optional类型:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    public String username;
    public Optional<String> nickname;
}

序列化的代码如下所示:

User user = new User("jalon", Optional.of("xiaowang"));
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(user);
System.out.println(str);

这里预期的结果应该是类似下面这样的:

{"username":"jalon","nickname":"xiaowang"}

但实际输出如下所示:

2. 原因分析

之所以序列化会输出{"present":true}这样的字符串,是因为Jackson默认的序列化行为导致;

Jackson默认的序列化会把所有public类型的get方法进行序列化,也就是取出对象中所有可访问的属性,然后填充到结果中;

而这里的Optional对象默认只有一个public类型的get方法,就是isPresent(),这个方法会返回true(当Optional的值不为空)或者false(当Optional的值为空);

Optional类的局部内容如下所示:

public final class Optional<T> {
    private final T value;
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

    public boolean isPresent() {
        return value != null;
    }

    @Override
    public String toString() {
        return value != null
            ? String.fORMat("Optional[%s]", value)
            : "Optional.empty";
    }
}

可以看到,虽然有一个value属性,但因为是private类型,所以无法直接被Jackson读取;

所以此时Jackson默认只读取了isPresent()方法,取得了true值;

3. 解决办法

幸运的是,Jackson官方已经出了一个Maven依赖,专门用来解决 由于Java8新增的数据类型导致的各种问题;

添加如下依赖:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
    <version>2.12.5</version>
</dependency>

然后在ObjectMapper对象中配置jdk8模块:objectMapper.reGISterModule(new Jdk8Module());

User user = new User("jalon", Optional.of("xiaowang"));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jdk8Module());
String str = objectMapper.writeValueAsString(user);
System.out.println(str);

最后输出符合预期,如下所示:

总结

Jackson在操作Optional类型的属性时,会由于Jackson自身的默认行为,导致输出的结果不符合预期;

解决办法就是加载jackson-datatype-jdk8依赖,然后全局注册Java8模块Jdk8Module

到此这篇关于Jackson处理Optional时遇到问题的解决与分析的文章就介绍到这了,更多相关Jackson处理Optional内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Jackson处理Optional时遇到问题的解决与分析

本文链接: https://www.lsjlt.com/news/139362.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作