
Boot4升后Jackson3怎么安全迁升到 Spring Boot 4 后JSON 这条线最容易踩的不是「缺依赖」而是默认栈已经切到 Jackson 3import找不到类、自定义ObjectMapper配了却不生效、日期从时间戳变成 ISO-8601——单测红一片值班却还按 Boot 3 / Jackson 2 习惯排查。本稿只做这条Jackson 安全迁清单包名怎么改、JsonMapper/JsonMapperBuilderCustomizer怎么换、use-jackson2-defaults何时开、三档过渡怎么选。DB migration starter 另文已写见 Boot4升后Flyway迁移不跑怎么改本稿不抢主线。依据以 Introducing Jackson 3 support in Spring2025-10-07、Spring Boot 4.0 Migration Guide §Upgrading Jackson以及 JSON features 为准。一、现象升完编译红或行为默认可变现场通常长这样parent / BOM 已是Spring Boot 4.0spring-boot-starter-web/spring-boot-starter-json仍按旧习惯写业务代码大量import com.fasterxml.jackson.databind.ObjectMapper编译报包找不到或注解包改错成tools.jackson.annotation官方例外仍是com.fasterxml编译过了但序列化结果与 Boot 3 对不上——属性顺序变了、日期不再是 timestamp。根因以官方口径为准Boot 4 默认 Jackson 3Jackson 2 支持以 deprecated 形式保留作 stop-gap不是「仍默认 2」。不要把现象猜成「Spring 配错了」或「只能硬扛双栈」。第一反应若是「把 Jackson 3 从 classpath 排除、强行拉回 2」先停一下官方过渡是spring-boot-jackson2模块与三档路径不是私自钉死一组与 Boot BOM 冲突的 Jackson 2 坐标。私钉版本号往往比按档位迁更难回滚。同系列升级里测试注解MockBean→MockitoBean是另一条线见已发 MockBean 文本稿只写 Jackson不展开测试装配。半迁移更隐蔽生产 POM 已随 Boot 4 BOM 带上 Jackson 3业务仍大面积手写new ObjectMapper()或测试按 Jackson 2 时间戳断言卡 JSON。本地「碰巧一致」过了CI 一换数据集就红。升级 PR 把「import / Customizer 类名」和「序列化样例断言」拆成两行勾选比事后对两套 JSON 做差分便宜。二、事实边界默认 3jackson2 模块未删Migration Guide / 博客写明Spring Boot 4.0 与 Framework 7.0引入 Jackson 3、弃用 Jackson 2最终移除、默认依赖与 classpath 检测切到 Jackson 3spring-boot-starter-json/spring-boot-starter-jackson走 Jackson 3。JSON 文档原话大意Jackson 3 is the preferred and default librarySupport for Jackson 2 is deprecated and will be removed in a future Spring Boot 4.x release。过渡模块spring-boot-jackson2以deprecated形式附带未来版本移除依赖坐标org.springframework.boot:spring-boot-jackson2配置前缀spring.jackson2对应 Boot 3.5 的spring.jackson。可排除spring-boot-jackson、改用spring-boot-jackson2作踏脚石。禁写成「已删除 / 不可用」也不鼓励新项目长期停在 2。Jersey 边界一句Boot 4.0 支持 Jersey 4.0后者尚未支持 Jackson 3用 Jersey 处理 JSON 时使用spring-boot-jackson2可替代或与spring-boot-jackson并存。本稿不展开 Jersey 迁移。建议先在依赖树确认主路径是spring-boot-jacksonJackson 3还是刻意切到了spring-boot-jackson2再谈业务改包。坐标和默认栈没钉死之前先改 POJO 注解包名很容易改出「注解还在 com.fasterxml、databind 却混双版本」的更难排障状态。三、包名多数 → tools.jackson注解例外仍 com.fasterxml官方三源一致多数模块 groupId / 包名从com.fasterxml.jackson改为tools.jackson例外是 jackson-annotations仍用com.fasterxml.jackson.coregroupId 与com.fasterxml.jackson.annotation包向后兼容。最小对照可单独编译的 import 示意// Jackson 3 主路径tools.jacksonimporttools.jackson.databind.json.JsonMapper;importtools.jackson.databind.SerializationFeature;// 示意具体 Feature 以 3.x API 为准// 注解仍留在 com.fasterxml不要改成 tools.jackson.annotationimportcom.fasterxml.jackson.annotation.JsonProperty;importcom.fasterxml.jackson.annotation.JsonIgnore;publicclassOrderView{JsonProperty(order_id)privateStringorderId;JsonIgnoreprivateStringinternalNote;// getters / setters 省略}注意 FasterXML 的「例外的例外」databind 内嵌注解如JsonSerialize/JsonDeserialize会迁到tools.jackson.databind.annotation勿与jackson-annotations的com.fasterxml.jackson.annotation混为一谈。成稿主线只钉死常用JsonProperty等仍写 com.fasterxml。迁移检查清单适合塞进升级 PR 描述业务import是否已从com.fasterxml.jackson.databind.*改到tools.jackson.*按模块实际使用面JsonProperty/JsonIgnore等是否仍为com.fasterxml.jackson.annotation未误改成tools.jackson.annotation是否已去掉「只声明 ObjectMapper bean」指望替换自动配置的写法Customizer 是否已改为JsonMapperBuilderCustomizer是否明确选了三档之一并在 DoD 里写清何时离开档位②/③。四、APIJsonMapper 不可变 JsonMapperBuilderCustomizerJackson 3 / Boot 4 侧以不可变JsonMapperJSON 专用extends ObjectMapper为主Spring不再提供Jackson2ObjectMapperBuilder等价物应用JsonMapper.Builder。类重命名Boot 3 / Jackson 2Boot 4 / Jackson 3Jackson2ObjectMapperBuilderCustomizerJsonMapperBuilderCustomizer可变ObjectMapper习惯不可变JsonMapper builderJsonComponentJacksonComponentJsonMixinJacksonMixin只声明一个ObjectMapperbean 不再足够替换自动配置——须定义JsonMapper或XmlMapperbean。自定义配置用JsonMapperBuilderCustomizer禁止继续用Jackson2ObjectMapperBuilderCustomizer去配 Jackson 3。importorg.springframework.boot.autoconfigure.jackson.JsonMapperBuilderCustomizer;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importtools.jackson.databind.json.JsonMapper;ConfigurationpublicclassJacksonConfig{BeanJsonMapperBuilderCustomizeralphabeticalAndDates(){returnbuilder-{// 按项目需要微调默认行为见下一节「怎么验」// builder 上的具体方法以 Boot 4 / Jackson 3 API 为准};}// 若必须完全替换自动配置的 mapper定义 JsonMapper bean而非仅 ObjectMapper// Bean// JsonMapper jsonMapper(JsonMapper.Builder builder) {// return builder.build();// }}「随便new ObjectMapper()改几项配置」不能指望自动替换 Boot 自动配置的JsonMapper——Migration Guide 点名的坑。若历史上有大量Jackson2ObjectMapperBuilder链式配置别「逐方法机械翻译」完事先分清哪些是在改默认行为更适合档位②的use-jackson2-defaults哪些是业务必需定制才落到JsonMapperBuilderCustomizer。「默认对齐」和「业务定制」拆开评审时不容易把缓冲开关当成永久配置。五、三档过渡全迁 3 / 开 defaults / 临时 jackson2博客推荐顺序preference①迁到 Jackson 3②迁 3 打开spring.jackson.use-jackson2-defaults③临时继续用 Jackson 2spring-boot-jackson2。属性名精确为spring.jackson.use-jackson2-defaults设为true时自动配置的JsonMapper默认尽量对齐 Spring Boot 3.x 下 Jackson 2 的默认。可选开启非默认 true——禁写成「默认就是 true」。# 档位 ②已迁 Jackson 3但希望默认行为先贴近 Boot3/Jackson2spring:jackson:use-jackson2-defaults:true档位 ③临时依赖org.springframework.boot:spring-boot-jackson2配置走spring.jackson2.*排障可短暂用升级 Definition of Done 里应写清「何时切回 3」。决策口诀能全迁就别停在 ②② 是行为缓冲不是终点③ 只作踏脚石Jersey 等边界场景才「必须 jackson2」。档位切换时注意前缀Jackson 3 主路径仍是spring.jackson.*临时 jackson2 对应spring.jackson2.*。两套前缀写进同一份application.yml却忘了 classpath 实际加载哪一套是半迁移里常见的「改了配置却没生效」。六、怎么验两条官方点名的默认差Spring 博客点名最易破测的默认变化优先用这两条做对照勿编造未点名的「空集合默认变了」MapperFeature.SORT_PROPERTIES_ALPHABETICALLY现为true—— 属性按字母序DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS原 SerializationFeature改为false—— 日期序列化为ISO-8601 字符串不再是 timestamp。验收建议升前升后各跑一条「同一 POJO → JSON 字符串」单测断言字段顺序与日期形态依赖树确认未误混「主路径仍是 jackson2、测试却按 jackson3 断言」的半迁移若开了use-jackson2-defaultstrue把「关开关再跑一遍」写进升级 PR避免缓冲档位掩盖真实行为差。其余 FasterXML 默认变更如 FAIL_ON_TRAILING_TOKENS 等以 MIGRATING_TO_JACKSON_3 为准本稿不展开臆造条目。importcom.fasterxml.jackson.annotation.JsonProperty;importtools.jackson.databind.json.JsonMapper;publicclassDateShapeSmoke{publicstaticclassEvent{JsonProperty(name)publicStringname;JsonProperty(when)publicjava.time.Instantwhen;}publicstaticvoidmain(String[]args)throwsException{JsonMappermapperJsonMapper.builder().build();EventenewEvent();e.nameboot4;e.whenjava.time.Instant.parse(2026-10-14T00:00:00Z);Stringjsonmapper.writeValueAsString(e);// Boot4 默认期望日期为 ISO-8601 字符串而非 epoch 数字System.out.println(json);if(!json.contains(2026-10-14)){thrownewIllegalStateException(dates not ISO-8601? gotjson);}}}具体 Feature 枚举类名以你环境 Jackson 3 为准断言目标仍是「日期非 timestamp」。升前升后各做一次「同一夹具 JSON ↔ 对象」往返先序列化再反序列化核对字段是否丢失、日期是否仍可解析。只断言「进程起来了」或「接口 200」抓不住静默形状变化。把「依赖是否已是 Jackson 3 主路径」和「样例 JSON 形状是否符合预期」写成两条独立断言别只过一条就合码。七、FAQQ1Boot4 为什么默认 Jackson3A官方引入 Jackson 3 为 preferred / defaultspring-boot-starter-json/spring-boot-starter-jackson切到 3Jackson 2 支持 deprecated将在未来 4.x 移除。Q2包名是不是全部改成 tools.jacksonA多数模块是jackson-annotations 例外JsonProperty等仍com.fasterxml.jackson.annotation。databind 内嵌注解另说勿与 annotations 包混淆。Q3还能 new ObjectMapper 改配置替代自动配置吗A不能指望。须面向JsonMapper自定义用JsonMapperBuilderCustomizer。只声明ObjectMapperbean 不够。Q4use-jackson2-defaults默认是 true 吗A不是。属性全名spring.jackson.use-jackson2-defaults设为true时才拉近 Boot3/Jackson2 默认。属档位②缓冲非默认开启。Q5spring-boot-jackson2 还能用吗A能但是deprecated stop-gap未删除配置前缀spring.jackson2。新项目勿长期停在 2。Jersey 尚不支持 Jackson 3 时用它一句边界。Q6JsonComponent呢A现为JacksonComponentJsonMixin→JacksonMixin。八、小结Boot4 上 Jackson 安全迁可压成五步认默认栈是 Jackson 3spring-boot-jackson2deprecated 未删仅过渡。改包名多数 →tools.jackson.*注解仍com.fasterxml.jackson.annotation。换 APIJsonMapperJsonMapperBuilderCustomizer勿再用旧 Customizer 配 3勿只声明ObjectMapperbean。选档位①全迁 3 → ②迁 3 use-jackson2-defaultstrue→ ③临时 jackson2能前勿后。验收属性字母序 日期 ISO-8601依赖树防双栈半迁移。把「是否已是 JsonMapper / Customizer 新名、而非旧 ObjectMapper 习惯」写进升级 Definition of Done比事后在生产日志里猜「为什么日期格式突然变了」便宜。DB starter、MockBean 等同系列坑拆文验收避免一个巨型 PR 里失败日志互相掩盖。落地时把「坐标与默认栈」和「序列化样例形状」拆成两次验收一次只看依赖与 Customizer 类名一次再跑夹具单测。混在同一巨大 PR 里评审很容易只盯 Jackson 小版本号漏掉仍残留的旧 Customizer 或误改的注解包名。