找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1928

积分

0

好友

252

主题
发表于 昨天 14:46 | 查看: 8| 回复: 0

对于资深 Spring Boot 开发者来说,Jackson 无疑是处理 Java 对象与 JSON 转换的事实标准。在 Spring Boot 4 中,一个显著的变化是默认的 JSON 库从 Jackson 2 切换到了 Jackson 3

这并非一次简单的版本号升级,其依赖结构也发生了有趣的变化:

spring-boot-starter-jackson (4.x)
├── tools.jackson.core:jackson-core:3.x   ← Jackson 核心库
└── com.fasterxml.jackson.annotation:jackson-annotations:2.x ← Jackson 注解

很多开发者在第一次查看项目依赖树时都会感到困惑:为什么项目里同时存在 Jackson 2 和 Jackson 3?

这其实是 Jackson 团队为了解决一个非常现实的工程问题而采取的策略:整个 Java 生态不可能一夜之间全部迁移到新版本。他们的解决方案非常巧妙:

  • 核心实现迁移到新包名
  • 注解继续沿用旧包名

这意味着你熟悉的 @JsonView@JsonFormat@JsonIgnore 等注解完全不需要修改,这种设计允许项目在 Jackson 2 和 3 之间进行渐进式、无痛迁移。

Spring Boot 4 默认升级到 Jackson 3 后,下面这 4 个核心变化,每一个都可能成为你升级路上的“坑点”,需要特别注意。

1. 包名变更:从 com.fasterxml.jacksontools.jackson

这是最直观、也最容易导致编译错误的变化。

// Jackson 2
import com.fasterxml.jackson.databind.ObjectMapper;

// Jackson 3
import tools.jackson.databind.ObjectMapper;

重要提示:只有核心 API 的包名发生了变化,所有注解(如 @JsonProperty)依然保留在 com.fasterxml.jackson.annotation 包下。

2. ObjectMapper 隐退,JsonMapper 成为主角

在 Jackson 2 中,ObjectMapper 是可变的(Mutable),这在多线程环境下存在安全隐患:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT); // 修改了实例状态

Jackson 3 则强制推行 Builder + Immutable(不可变) 模式,这本身就是一种优秀的 System Design 实践,能提升应用的健壮性:

JsonMapper mapper = JsonMapper.builder()
    .enable(SerializationFeature.INDENT_OUTPUT)
    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
    .build(); // 构建后实例不可变

一旦调用 build() 方法,配置便被锁定,生成的 JsonMapper 实例可以安全地在多线程间共享,天然具备线程安全性。这是 Jackson 3 在 API 设计上一次重要的升级。

在 Jackson 3 中,直接 new ObjectMapper() 得到的将是仅包含默认配置的实例。如需自定义配置,必须使用 JsonMapper.builder() 来创建不可变的、线程安全的实例。

3. 日期序列化默认格式变化(极易踩坑)

这是向后兼容性方面最容易出问题的一点。Jackson 3 更改了日期/时间类型的默认序列化格式。

版本 默认序列化格式
Jackson 2 时间戳(如 1767588151648
Jackson 3 ISO-8601 字符串(如 "2026-01-05T02:02:31.648Z"
// Jackson 2 默认输出
{"nowDate": 1767588151648}

// Jackson 3 默认输出
{"nowDate": "2026-01-05T02:02:31.648Z"}

对前端而言,ISO-8601 格式的字符串更友好、更易读。但这会导致两个常见问题:

  • 依赖精确时间戳进行断言的旧测试用例会失败。
  • 与特定时间格式强绑定的接口契约或 Mock 数据需要同步调整。

临时兼容方案:在迁移初期,可以通过配置让 Jackson 3 暂时保持 Jackson 2 的默认行为。

spring:
  jackson:
    use-jackson2-defaults: true

4. 告别 Checked Exception

这个改动让许多 Java 开发者拍手称快。Jackson 2 中,许多方法会抛出 IOException 这类受检异常(Checked Exception),代码不得不包裹在 try-catch 块中:

// Jackson 2
try {
    objectMapper.readValue(json, MyClass.class);
} catch (IOException e) {
    // 异常处理
}

而在 Jackson 3 中,所有异常都继承自 JacksonException,而它是一个运行时异常(RuntimeException):

// Jackson 3
jsonMapper.readValue(json, MyClass.class); // 无需捕获受检异常

最直接的好处体现在现代 Java 的流式编程中,代码变得更加简洁:

// Jackson 2:在lambda中直接抛出受检异常会导致编译错误
list.stream()
    .map(o -> objectMapper.writeValueAsString(o)) // 编译报错!
    .toList();

// Jackson 3:完全没问题,代码更优雅
list.stream()
    .map(o -> jsonMapper.writeValueAsString(o))
    .toList();

这一设计充分考虑了现代 Java 的编码习惯,让 API 用起来更加顺手。

总结

Spring Boot 4 拥抱 Jackson 3 是一次重要的生态升级,带来了更安全的 API 设计、更现代的异常处理机制。升级时,请重点关注包名变更不可变的 JsonMapper日期格式默认值以及异常类型这四个核心变化点。合理利用 use-jackson2-defaults 配置可以平滑过渡。理解这些变化,能帮助你在技术升级浪潮中更加从容。如果你想深入探讨这些技术细节或获取更多实战项目经验,欢迎到 云栈社区 与更多开发者交流。




上一篇:Python脚本监控利器:pushplus实现微信通知推送
下一篇:iPhone 16e成功运行macOS Sequoia,开发者通过驱动移植突破苹果限制
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-11 22:08 , Processed in 0.192072 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表