---
url: /diary/spring/springboot4-jackson/index.md
description: Spring Boot 4 中 Jackson 3 的配置方式、与 Jackson 2 的差异对比、类名重命名、配置属性变更及三种兼容迁移方案。
---
## Jackson 3 — 最大的破坏性变更

Spring Boot 4 将 JSON 库从 **Jackson 2 升级到 Jackson 3**。这是此次升级中影响面最广的破坏性变更。

### 为什么影响大？

Jackson 3 对 Jackson 2 **不完全兼容**，核心变化包括：

| 变更项 | Jackson 2（Spring Boot 3.x） | Jackson 3（Spring Boot 4.x） |
|---|---|---|
| 核心包名 | `com.fasterxml.jackson` | `tools.jackson` |
| Maven Group ID | `com.fasterxml.jackson.*` | `tools.jackson.*` |
| 注解包名 | `com.fasterxml.jackson.annotation` | **不变**，注解模块保持原包名 |

> 注意：`jackson-annotations` 模块的 `com.fasterxml.jackson.core` GroupId 和 `com.fasterxml.jackson.annotation` 包名**没有变**。

## 类名重命名

Spring Boot 4 中 Jackson 相关的工具类也做了重命名：

| 旧名称（Spring Boot 3.x） | 新名称（Spring Boot 4.x） | 用途 |
|---|---|---|
| `JsonObjectSerializer` | `ObjectValueSerializer` | JSON 序列化器基类 |
| `JsonValueDeserializer` | `ObjectValueDeserializer` | JSON 反序列化器基类 |
| `Jackson2ObjectMapperBuilderCustomizer` | `JsonMapperBuilderCustomizer` | ObjectMapper 定制接口 |
| `@JsonComponent` | `@JacksonComponent` | 注册自定义序列化/反序列化组件 |
| `@JsonMixin` | `@JacksonMixin` | 注册 Mixin 类 |

### 迁移示例

```java
// Spring Boot 3.x
@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> builder.dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    }
}

// Spring Boot 4.x
@Configuration
public class JacksonConfig {
    @Bean
    public JsonMapperBuilderCustomizer customizer() {
        return builder -> builder.dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    }
}
```

## 配置属性变更

### 属性路径重组

```yaml
# Spring Boot 3.x
spring:
  jackson:
    serialization:
      indent-output: true
      write-dates-as-timestamps: false
    deserialization:
      fail-on-unknown-properties: false
    parser:
      allow-comments: true

# Spring Boot 4.x（JSON 专有属性已重组）
spring:
  jackson:
    json:
      read:          # 对应 Jackson 3 的 JsonReadFeature
        allow-comments: true
      write:         # 对应 Jackson 3 的 JsonWriteFeature
        indent-output: true
```

### 模块自动发现行为变更

Spring Boot 4 中，Jackson 会**自动检测 classpath 上的所有模块并注册**到 mapper 实例。而 Spring Boot 3 中只有"已知模块"会自动注册。

如果不需要此行为：

```properties
spring.jackson.find-and-add-modules=false
```

## 新的 Jackson Starter

```xml
<!-- Spring Boot 4.x 专用 Jackson starter（Jackson 3） -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jackson</artifactId>
</dependency>
```

## 三种 Jackson 2 兼容方案

如果你暂时不想迁移到 Jackson 3，Spring Boot 4 提供了三种兼容方案。

### 方案一：使用兼容性默认值（推荐）

让 Jackson 3 的行为尽量对齐 Jackson 2：

```properties
spring.jackson.use-jackson2-defaults=true
```

这是最简单的方案，适合 Jackson 使用不复杂的项目。

### 方案二：使用 Jackson 2 兼容模块

引入专门的 Jackson 2 兼容模块（**已标记为 Deprecated，仅作过渡**）：

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-jackson2</artifactId>
</dependency>
```

Jackson 2 的配置属性在 `spring.jackson2.*` 下，与 Spring Boot 3.5 的 `spring.jackson.*` 一致：

```yaml
spring:
  jackson2:
    serialization:
      indent-output: true
    deserialization:
      fail-on-unknown-properties: false
```

### 方案三：按模块指定 Jackson 2

如果你只是某个特定模块需要 Jackson 2，可以精确指定：

```properties
# HTTP 消息转换器使用 Jackson 2
spring.http.converters.preferred-json-mapper=jackson2
spring.http.codecs.preferred-json-mapper=jackson2

# GraphQL RSocket 使用 Jackson 2
spring.graphql.rsocket.preferred-json-mapper=jackson2

# WebSocket Messaging 使用 Jackson 2
spring.websocket.messaging.preferred-json-mapper=jackson2

# RSocket 使用 Jackson 2
spring.rsocket.preferred-mapper=jackson2
```

## 常用配置示例

### 基础配置

```yaml
spring:
  jackson:
    # 日期格式
    date-format: yyyy-MM-dd HH:mm:ss
    # 时区
    time-zone: Asia/Shanghai
    # 默认属性包含策略
    default-property-inclusion: non_null
    json:
      write:
        indent-output: true
      read:
        allow-comments: true
        allow-single-quotes: true
```

### 自定义序列化/反序列化

```java
// Spring Boot 4.x 使用 @JacksonComponent
@JacksonComponent
public class LocalDateTimeSerializer extends ObjectValueSerializer<LocalDateTime> {
    public LocalDateTimeSerializer() {
        super(LocalDateTime.class);
    }

    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
        gen.writeString(value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    }
}
```

### Mixin 使用

```java
// Spring Boot 4.x 使用 @JacksonMixin
@JacksonMixin(type = User.class)
public abstract class UserMixin {
    @JsonProperty("user_name")
    private String name;

    @JsonIgnore
    private String password;
}
```

## 迁移建议

1. **新项目**：直接使用 Jackson 3，配合 `spring-boot-starter-jackson`
2. **简单项目**：方案一（`use-jackson2-defaults=true`）最快
3. **重度依赖 Jackson 2 的项目**：方案二（`spring-boot-jackson2`）过渡，逐步迁移
4. **混合场景**：方案三按模块精细控制

Jackson 3 的包名变化是硬伤——所有 `import com.fasterxml.jackson` 都需要改为 `import tools.jackson`（注解包除外）。建议配合 IDE 的全局替换功能批量处理。

***

> 相关文章：
>
> * [Spring Boot 4 概览与迁移指南](./01.SpringBoot4概览与迁移指南.md)
> * [Redis 集成使用](./03.Redis集成使用.md)
> * [MyBatis-Flex 实战](./04.MyBatis-Flex实战.md)
> * [其他核心变更](./05.其他核心变更.md)
