Spring Boot 4 Jackson 序列化 LocalDateTime 配置

本文介绍 Spring Boot 4 Jackson 序列化 LocalDateTime 配置

Spring Boot 4.x 升级到 Jackson 3.x 后,部分配置项名称和用法发生了变化。本文将介绍如何配置 Jackson 序列化 LocalDateTime。

依赖修改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- Spring Boot 3.x -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

<!-- Spring Boot 4.x -->
<dependency>
    <groupId>tools.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

Jackson 序列化 LocalDate 和 LocalDateTime

Spring Boot 3

Jackson 2 时使用如下方式序列化 LocalDate、LocalDateTime:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.format.DateTimeFormatter;

@Configuration
public class JacksonConfig {

    private final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            builder.serializers(
                    new LocalDateTimeSerializer(DATE_TIME_FORMAT),
                    new LocalDateSerializer(DATE_FORMAT));
            builder.deserializers(
                    new LocalDateTimeDeserializer(DATE_TIME_FORMAT),
                    new LocalDateDeserializer(DATE_FORMAT));
        };
    }
}

Spring Boot 4

来到 Jackson 3 以后,序列化 LocalDate 和 LocalDateTime 的方式发生了变化,需要使用新的类和方法进行配置,有两种方式实现(其他类型同理):

方式一

基于 SimpleModule 实现相应类的 Serializer 和 Deserializer。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.cfg.DateTimeFeature;
import tools.jackson.databind.ext.javatime.deser.LocalDateDeserializer;
import tools.jackson.databind.ext.javatime.deser.LocalDateTimeDeserializer;
import tools.jackson.databind.ext.javatime.ser.LocalDateSerializer;
import tools.jackson.databind.ext.javatime.ser.LocalDateTimeSerializer;import tools.jackson.databind.module.SimpleModule;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class JacksonConfig {
    
    private static final String DATE_FORMAT = "yyyy-MM-dd";
    
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Bean
    public JsonMapperBuilderCustomizer jacksonCustomizer() {

        // LocalDateTime
        LocalDateTimeSerializer localDateTimeSerializer = new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT));
        LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT));

        // LocalDate
        LocalDateSerializer localDateSerializer = new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_FORMAT));
        LocalDateDeserializer localDateDeserializer = new LocalDateDeserializer(DateTimeFormatter.ofPattern(DATE_FORMAT));

        SimpleModule module = new SimpleModule("TOFUWINE-WORKBENCH-MODULE");
        module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer)
                .addSerializer(LocalDateTime.class, localDateTimeSerializer)
                .addDeserializer(LocalDate.class, localDateDeserializer)
                .addSerializer(LocalDate.class, localDateSerializer);

        return builder -> {
            builder.enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
                    .addModule(module)
                    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 忽略未知字段 (避免版本升级等原因导致反序列化失败)

        };
    }
}

方式二

基于 config override 实现。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.cfg.DateTimeFeature;
import tools.jackson.databind.ext.javatime.deser.LocalDateDeserializer;
import tools.jackson.databind.ext.javatime.deser.LocalDateTimeDeserializer;
import tools.jackson.databind.ext.javatime.ser.LocalDateSerializer;
import tools.jackson.databind.ext.javatime.ser.LocalDateTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class JacksonConfig {
    
    private static final String DATE_FORMAT = "yyyy-MM-dd";
    
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Bean
    public JsonMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            builder.enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)  // DATE 转时间戳
                    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // 忽略未知字段 (避免版本升级等原因导致反序列化失败)
                    .withConfigOverride(LocalDateTime.class,
                            time -> time.setFormat(JsonFormat.Value.forPattern(DATE_TIME_FORMAT)))
                    .withConfigOverride(LocalDate.class,
                            date -> date.setFormat(JsonFormat.Value.forPattern(DATE_FORMAT)));

        };
    }
}

注意:JsonFormat 仍是 com.fasterxml.jackson 包下的。这是因为 Jackson 3.x 将不再包含独立的注解模块,而是继续使用 2.x 的模块。

1
2
3
4
5
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>${jackson.version.annotations}</version>
</dependency>

如果有其他类型希望自定义实现序列化/反序列化,均可以参考上述方式实现。

参考网站

如果本文对您有所帮助,欢迎打赏支持作者!

Licensed under CC BY-NC-SA 4.0
最后更新于 2026-08-30 16:57
使用 Hugo 构建
主题 StackJimmy 设计