java - 为什么 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
不同的值。它转换null
为Optional.empty()
,而它以前没有这样做。
我想恢复旧的行为。有谁知道如何防止 Spring 将 null 转换为空 Optionals 并将其保留为 null?是否有新的默认配置?我没有找到。
解决方案
看来我不能再java.util.Optional
用于我的目的了。Spring 开发人员扩展ProjectingMethodInterceptor
为将null
值转换为使用的包装器类型的空表示(Optional.empty()
在我的情况下)。
这也适用于其他包装器类型:
com.google.common.base.Optional
scala.Option
io.vavr.control.Option
推荐阅读
- c++ - 如何使用 gtest 模拟 EXPECT_CALL
- javascript - 如何从数字数组中删除数学抵消值?
- swift - 使用组合组合先前的值
- c++ - 将共享库与 GCC 链接时的问题
- java - 我们如何 fork opencv-android repo 并在自己的项目中使用它?
- cryptocurrency - TradingView 图表库:如何在图表中添加加密货币交换符号?
- javascript - 使用 react material-ui 对话框进行奇怪的重新渲染行为
- python - 如何使此函数中的代码重复?(Python)
- python - atexit._run_exitfuncs 中的 Python concurrent.futures 错误:OSError:句柄已关闭,仅在 Visual Studio 调试模式下运行
- python - 将列表转换为字符串?