Jackson3来了,变化真大!

发布时间:2026/7/21 22:39:13

Jackson3来了,变化真大! 前言最近在做Spring Boot 4升级的时候发现一个非常普遍的现象——大部分人被Jackson 3这个“隐形炸弹”炸得措手不及。项目启动后控制台报了一堆莫名其妙的错。翻来覆去一看原来不是业务代码的问题是Jackson升级带来的破坏性变更。“Jackson不就是个JSON序列化工具吗升级一下能有什么大不了的”如果你这么想那说明你还没真正理解Jackson在Java生态中的位置。Jackson不仅仅是“一个JSON库”它是Java生态中事实上的JSON标准实现。Spring Boot、微服务通信、Redis序列化、日志解析——几乎所有涉及到JSON的地方底层都在用Jackson。从Jackson 2.x升级到3.x不是一次“无感升级”。它是Jackson时隔8年的第一次大版本号变更。从2017年底开始酝酿到2025年10月3日正式发布GA版本前后经历了10个RC版本。今天这篇文章我就把Jackson 3的新功能和迁移要点从头到尾给你拆解一遍。希望对你会有所帮助。更多项目实战在我的技术网站susan.net.cn/project一、Jackson 3到底“新”在哪在聊具体功能之前我们先建立一个整体认知。Jackson 3是一次价值取向非常明确的重构型演进。如果说Jackson 2更偏向“兼容一切历史包袱”那么Jackson 3的目标非常清晰——安全、类型清晰、面向现代Java。这张图基本概括了Jackson 3的核心变化。下面我逐一给你拆解。二、JDK基线升级到Java 17这是Jackson 3最根本的变化。Jackson 3.x要求JDK 17。Jackson 2.x最低支持JDK 8。从JDK 8到JDK 17中间隔了9年、4个LTS版本。这个升级意味着Jackson 3可以充分利用Java 17的新特性——Records、Sealed Classes、Pattern Matching等。对你的影响如果你的项目还在JDK 8或11上想用Jackson 3必须先升级JDK。好消息是Spring Boot 3.x已经要求JDK 17了所以大部分新项目其实已经满足了这个条件。三、包名和groupId全面变更这是最“显眼”的变更也是你升级时第一个会碰到的编译错误。对比项Jackson 2.xJackson 3.xMaven groupIdcom.fasterxml.jacksontools.jacksonJava包名com.fasterxml.jackson.xxxtools.jackson.xxx注解包名com.fasterxml.jackson.annotation保持不变// Jackson 2.x 的写法 import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.JsonParser; // Jackson 3.x 的写法 import tools.jackson.databind.json.JsonMapper; import tools.jackson.core.JsonParser;为什么注解包名不变这是一个非常巧妙的设计。Jackson团队把注解库jackson-annotations留在了原来的groupId和包名下只把核心处理逻辑移到了tools.jackson。Jackson 3.0使用的是jackson-annotations2.20版本。这意味着Jackson 2和Jackson 3可以在同一个项目中共存。你的核心应用可以用Jackson 3老旧第三方依赖库依然可以用Jackson 2互不干扰。但要注意一个例外jackson-databind内部的注解如JsonSerialize、JsonDeserialize会移动到新包tools.jackson.databind.annotation。四、ObjectMapper变成不可变的JsonMapper这是Jackson 3影响面最大的变更。在Jackson 2.x中ObjectMapper是可变的。你可以这样写// Jackson 2.x - 可变配置 ObjectMapper mapper new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); // 随时可以改 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 状态可以在任何时候被修改这种设计在多线程环境下会引发问题——一个线程修改了配置另一个线程正在使用就会出现不可预知的行为。Jackson 3.x强制使用Builder模式构建完成后配置就被锁定了// Jackson 3.x - 不可变Builder模式 JsonMapper mapper JsonMapper.builder() .enable(SerializationFeature.INDENT_OUTPUT) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); // 配置一旦build()就被锁定必须使用格式对齐的子类在Jackson 3中必须使用与数据格式匹配的ObjectMapper子类// Jackson 2.x - 可以混用 ObjectMapper mapper new ObjectMapper(new YAMLFactory()); // Jackson 3.x - 必须使用对应的Mapper JsonMapper jsonMapper JsonMapper.builder().build(); // JSON YAMLMapper yamlMapper YAMLMapper.builder().build(); // YAML XmlMapper xmlMapper XmlMapper.builder().build(); // XML禁止new ObjectMapper(new YAMLFactory())这种写法。五、异常体系重构Jackson 2.x使用的是检查型异常Checked Exception——JsonProcessingException是Exception的子类你必须显式try-catch或throws。Jackson 3.x改为非检查型异常Unchecked ExceptionJackson 2.xJackson 3.xJsonProcessingExceptionJacksonException基类JsonParseExceptionStreamReadExceptionJsonEOFExceptionUnexpectedEndOfInputException// Jackson 2.x - 必须处理检查型异常 try { User user mapper.readValue(json, User.class); } catch (JsonProcessingException e) { // 必须处理 } // Jackson 3.x - 非检查型异常可以选择不捕获 User user mapper.readValue(json, User.class); // 如果出错抛出JacksonException运行时异常这个改动让Jackson的API更符合现代Java编程习惯和Spring、Lombok等主流框架保持一致。六、默认配置全面调整Jackson 3改了大量默认配置。我挑几个最可能“炸到你”的来说。6.1 日期序列化从时间戳变成ISO-8601字符串这是最容易被忽略、影响面最大的变更之一。// Jackson 2.x 默认2026-07-20 12:00:00 → 1721462400000时间戳 // Jackson 3.x 默认2026-07-20 12:00:00 → 2026-07-20T12:00:00ZISO-8601字符串如果你的前端代码依赖时间戳格式升级后接口返回的数据格式会变。好消息是可以显式配置改回来JsonMapper mapper JsonMapper.builder() .enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // 改回时间戳 .build();6.2 原始类型空值从宽松变成严格Jackson 3.x将FAIL_ON_NULL_FOR_PRIMITIVES的默认值从false改为了true。// 假设你有这样的DTO public class User { private int age; // 原始类型int } // Jackson 2.xJSON中age为null时默认赋值为0 // Jackson 3.xJSON中age为null时抛出JsonMappingException这个变更会让很多“以前能跑”的代码突然报错。解决方案要么把int改成Integer要么显式禁用这个特性。6.3 月份计数从0基变成1基Java的java.util.Date中月份是从0开始的0一月。Jackson 3.x将DateTimeFeature.ONE_BASED_MONTHS的默认值从false改为了true。这意味着序列化/反序列化时月份的处理方式发生了变化。如果你的代码依赖“0一月”的逻辑升级后需要特别注意。七、性能与内存优化Jackson 3不只是“改API”在性能和内存方面也做了大量优化。7.1 BeanDescription懒加载优化Jackson 3.0对BeanDescription的实现引入了Supplier模式实现延迟加载。对于简单类型或不需要完整BeanDescription的场景避免了不必要的解析开销。这减少了临时对象的创建和GC压力。7.2 RecyclerPool延迟初始化Jackson Core 3.0优化了RecyclerPool的初始化策略。在高频使用Jackson的应用中能显著提升内存使用效率。7.3 字段名去重禁用Jackson 3.0将TokenStreamFactory.Feature.INTERN_FIELD_NAMES的默认值改为false。这意味着JSON字段名不再被自动缓存到字符串常量池中减少了内存占用。八、模块整合少了三个依赖在Jackson 2.x中为了支持Java 8的新特性你需要额外引入三个模块!-- Jackson 2.x 需要额外引入 -- dependency groupIdcom.fasterxml.jackson.module/groupId artifactIdjackson-module-parameter-names/artifactId /dependency dependency groupIdcom.fasterxml.jackson.datatype/groupId artifactIdjackson-datatype-jdk8/artifactId /dependency dependency groupIdcom.fasterxml.jackson.datatype/groupId artifactIdjackson-datatype-jsr310/artifactId /dependencyJackson 3.x中这三个模块已经整合到jackson-databind中。不需要单独引入了。

相关新闻