关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言
Spring Boot 4.0(2025年11月 GA)将默认 JSON 处理库从 Jackson 2 升级为 Jackson 3,这是本次大版本升级中影响面最广的破坏性变更之一。
本节将梳理 Jackson 2 → 3 的核心变化,以便后续使用。
02 版本和坐标的变化
2.1 变化
Jackson 2的坐标:
xml
<!-- Jackson 2 (Boot 3.x) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
包名的前缀:com.fasterxml.jackson.*
JDK要求:JDK 8+
Jackson 3的坐标:
xml
<!-- Jackson 3 (Boot 4.x) -->
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
包名的前缀:tools.jackson.*
JDK要求:JDK 17+
这个包名都改了,改动确实很大。
2.2 不变
虽然主要的包都发生了变化,但是注解的包没有变。
java
// ✅ 注解包名在 Jackson 2 和 3 中保持一致
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.JsonFormat;
03 核心API的变化
3.1 ObjectMapper → JsonMapper
Jackson 3 最重要的架构变化:从可变的 ObjectMapper 切换到不可变的 JsonMapper 。JsonMapper继承ObjectMapper,既可以通过构造函数像使用ObjectMapper一样创建对象,也可以通过Build的方式构建对象,还提供了静态方法直接使用。
先看看Jackson 2的方式:
java
// ── Jackson 2:可变配置 ──
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 随时可以修改 mapper 状态
Jackson 3直接使用JsonMapper,在ObjectMapper扩展了使用。
java
// ── Jackson 3:不可变 Builder 模式 ──
JsonMapper mapper = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.serializationInclusion(JsonInclude.Include.NON_NULL)
.build();
// build() 后配置锁定,线程安全
// 从已有 mapper 重建
JsonMapper newMapper = mapper.rebuild()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
// 静态方法
JsonMapper mapper = JsonMapper.shared();
使用起来更加灵活!
3.2 Spring Boot 注入变化
Spring Boot 4 自动配置既支持 JsonMapper 也支持 ObjectMapper。
java
// Spring Boot 3.x --- 注入 ObjectMapper
@Autowired
private ObjectMapper objectMapper;
// Spring Boot 4.x --- 注入 JsonMapper或者objectMapper都可以
@Autowired
private ObjectMapper objectMapper;
@Autowired
private JsonMapper jsonMapper;
3.3 异常变化
Jackson 3 从受检异常(Checked Exception)切换到非受检异常(Unchecked Exception)。
异常体系对照:
html
Jackson 2.x:
IOException (checked)
└── JsonProcessingException
├── JsonParseException
├── JsonMappingException
└── JsonGenerationException
Jackson 3.x:
RuntimeException (unchecked)
└── JacksonException
├── StreamReadException (替代 JsonParseException)
├── StreamWriteException (替代 JsonGenerationException)
└── DatabindException (替代 JsonMappingException)
在 ObjectMapper(Jackson 3 中由 JsonMapper 继承)里:
java
// Jackson 2.x --- 受检异常,必须 catch 或 throws
public String writeValueAsString(Object value) throws JsonProcessingException {
// Jackson 3.x --- 非受检异常,不强制处理
public String writeValueAsString(Object value) throws JacksonException {
虽然方法签名仍声明了 throws JacksonException,但因为它继承的是 RuntimeException,编译器不再强制你 catch 或在调用方法上声明 throws。这纯粹是为了文档可读性保留的声明。
3.5 日期序列化默认值
日期类型在序列化中展示不同
java
// Jackson 2 输出
{"createdAt": 1699257000000}
// Jackson 3 输出
{"createdAt": "2025-11-06T05:30:00"}
WRITE_DATES_AS_TIMESTAMPS独属于Jackson 2,Jackson 3中没有这个参数,如果想要保持时间戳的输出,需要特别处理。
java
SimpleModule timestampModule = new SimpleModule();
timestampModule.addSerializer(Date.class, new DateTimestampSerializer());
JsonMapper timestampMapper = JsonMapper.builder()
.addModule(timestampModule).build();
/**
* 将 java.util.Date 序列化为 epoch 毫秒时间戳
*/
static class DateTimestampSerializer extends StdSerializer<Date> {
DateTimestampSerializer() {
super(Date.class);
}
@Override
public void serialize(Date value, JsonGenerator gen, SerializationContext ctxt) {
gen.writeNumber(value.getTime());
}
}
04 小结
Spring Boot 4.x 的 Jackson 升级不是简单的版本号替换,而是一次架构级重构。使用jackson 3 的老铁可要主要注意了,小心踩坑!