首页 > 解决方案 > 为什么 ProjectionFactory 将 null 转换为空 Optionals?

问题描述

最近我将我的项目从 Spring Boot 2.1.0 更新到 Spring Boot 2.5.6。从那时起,我看到了 JSON 序列化的差异。

为了区分情况(a)任何值,(b)显式 null和(c)我使用的没有值java.util.Optional和杰克逊的@JsonInclude(NON_NULL)注释。此外,我使用 Spring Data JPA 的投影模式来定义 JSON 格式,如下所示:

public interface MyProjection {

    @JsonInclude(Include.NON_NULL)
    Optional<String> getMyAttribute();
}

这与 Spring Boot 2.1.0 完美配合。

字段值 呈现的 JSON
Optional.of("something") { "myAttribute": "something" }
Optional.empty() { "myAttribute": null }
null {}

截至目前(在我更新到 Spring Boot 2.5.6 之后)null呈现如下Optional.empty()

字段值 呈现的 JSON
Optional.of("something") { "myAttribute": "something" }
Optional.empty() { "myAttribute": null }
null { "myAttribute": null }

我的第一个假设是杰克逊NON_NULL不再与Optional. 但事实并非如此。正如@Pedro 所说,它工作正常。经过一番调查,我发现 SpringProjectionFactory似乎处理null不同的值。它转换nullOptional.empty(),而它以前没有这样做。

我想恢复旧的行为。有谁知道如何防止 Spring 将 null 转换为空 Optionals 并将其保留为 null?是否有新的默认配置?我没有找到。

标签: javaspringspring-bootspring-data-jpa

解决方案


看来我不能再java.util.Optional用于我的目的了。Spring 开发人员扩展ProjectingMethodInterceptornull值转换为使用的包装器类型的表示(Optional.empty()在我的情况下)。

这也适用于其他包装器类型:

  • com.google.common.base.Optional
  • scala.Option
  • io.vavr.control.Option

推荐阅读