欢迎来到代码驿站!

JAVA代码

当前位置:首页 > 软件编程 > JAVA代码

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

时间:2023-01-30 10:34:23|栏目: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

上一篇:Java JDBC批量执行executeBatch方法详解

栏    目:JAVA代码

下一篇:Java 全面系统介绍反射的运用

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

本文地址:http://www.codeinn.net/misctech/224740.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有