Spring Boot 4.0 全面拥抱 Jackson 3!小心有坑~
往期热门文章: 1、为什么大厂一般不推荐使用@Transactional? 2、又一款开源、强大的工作流自动化神器,吃到细糠了! 3、JDK25都出来了,但为什么很多公司还在坚持用JDK8? 4、15 万个 ClawdBot 涌进 AI 社交网站,但人类只能围观。 5、Spring6.0+Boot3.0:秒级启动、万级并发的开发新姿势
升级 Spring Boot 4 后,如果你执行 mvn dependency:tree 或者 ./gradlew dependencies,你会发现一个非常奇葩的现象:
spring-boot-starter-jackson (4.x)
├── tools.jackson.core:jackson-core:3.x ← Jackson 核心实现(新包)
└── com.fasterxml.jackson.annotation:jackson-annotations:2.x ← Jackson 注解(旧包)

很多同学第一反应是“依赖冲突了”。其实不然,这是 Jackson 团队一次非常工程化、现实主义的设计。
他们意识到整个 Java 生态(数以万计的第三方库)不可能一夜之间全改包名。于是采取了“核心实现迁新包,注解沿用旧包”的策略。这意味着你常用的 @JsonProperty、@JsonIgnore 完全不用动,这种渐进式迁移的思路,值得我们学习。
Jackson 3 的 4 大 Breaking Changes
Spring Boot 4 默认升级到 Jackson 3 后,绝对不是换个版本号那么简单。下面这四个变化,如果不提前复盘,线上准得出 Bug。
1. 包名大重组:从 com.fasterxml 到 tools.jackson
这是最直观的改动。所有的核心类都挪窝了:
// Jackson 2 (旧)
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
// Jackson 3 (新)
import tools.jackson.core.JacksonException;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.ObjectMapper;
只有核心 API 换了包名,注解依然在旧包下。别傻傻地去全局替换所有的 com.fasterxml,那样你的注解就全报错了!
2. ObjectMapper 退出舞台,JsonMapper 强制登场
在 Jackson 2 时代,ObjectMapper 是可变的(Mutable),这在多线程环境下其实是个隐患。
Jackson 3 强制推行 Builder + Immutable(不可变) 模式:
// Jackson 3 推荐写法
JsonMapper mapper = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
一旦执行了 build(),配置就被彻底锁死。
这种设计让实例变得天然线程安全。如果你直接 new ObjectMapper(),只能拿到默认配置,想自定义?对不起,请用 Builder。
3. 日期序列化更改
这是最容易导致前后端联调失败的地方。Jackson 3 改变了默认的日期输出格式:
| 维度 | Jackson 2 默认行为 | Jackson 3 默认行为 |
|---|---|---|
| 输出格式 | 时间戳 (Long) | ISO-8601 字符串 |
| 示例结果 | {"now": 1767588151648} |
{"now": "2026-01-05T02:02:31Z"} |
避坑提醒:如果你的前端代码写死了按时间戳解析,或者测试用例里有硬编码的时间戳断言,升级后会全线崩掉。
【过渡方案】:如果你想保持现状,可以在 application.yml 里紧急救火:
spring:
jackson:
use-jackson2-defaults: true # 强制 Jackson 3 模拟 2 的行为,不推荐
4. 异常处理:Checked Exception 的终结
作为 Java 开发者,你一定被 try-catch 包裹 readValue 恶心过。Jackson 3 终于顺应民意,把所有异常都改成了 RuntimeException。
对比感受一下:
// Jackson 3:Lambda 表达式的福音
list.stream()
.map(o -> jsonMapper.writeValueAsString(o)) // 不再强制 catch IOException
.toList();
这是真正为现代 Java 写法(Stream/Lambda)服务的设计。虽然看起来改动小,但对代码整洁度的提升是巨大的。
总结
好的框架升级,不应该只是追新,更要理解背后的设计意图。Jackson 3 的这次升级,完美诠释了什么是“在理想主义(线程安全、Runtime 异常)与工程现实(保留旧注解包名)之间跳舞”。
往期热门文章:
1、一款开源、现代化的数据库备份利器 2、这两个网站,一个可以当时间胶囊,一个充满了赛博菩萨。 3、零停机更新代码:SpringBoot 新技能,妙啊~ 4、两小时撸完日志链路串连方案 5、腾讯又开源了一个顶级 AI 项目! 6、Maven 4 要来了:15 年后,Java 构建工具迎来“彻底重构” 7、Spring Boot 插件化开发模式,真香! 8、雪花算法ID重复了?惨痛教训:请勿轻易造轮子! 9、唉!Stack Overflow彻底凉了,比18年前上线首月问题数量还少 10、为什么程序员不自己开发微X小程序这类似的东西赚钱?
更多推荐


所有评论(0)