Spring Boot 踩坑记录:为什么 application.yml 中的 Jackson 日期格式化对 LocalDateTime 不生效?

Spring Boot 踩坑记录:为什么 application.yml 中的 Jackson 日期格式化对 LocalDateTime 不生效?

_

💡 问题现象

在开发 Spring Boot 后端项目时,为了让接口返回给前端的 JSON 日期格式保持统一(去掉默认的带 T 的格式),我们通常会在 application.yml 中加上这样一段 Jackson 的全局配置:

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: Asia/Shanghai

满心欢喜地以为配置完毕,启动项目用 Postman 调接口一看,傻眼了。如果你的实体类使用的是 Java 8 推出的 LocalDateTime,返回的 JSON 数据居然还是长这样:

{
  "createTime": "2026-08-13T15:43:45",
  "updateTime": "2026-08-13T15:43:45"
}

那个碍眼的 T 依然坚挺地杵在中间,仿佛在嘲笑我们的配置文件毫无作用。这是为什么呢?

🔍 原因分析

其实这不是 Spring Boot 的 Bug,而是 Jackson 处理不同时间类的机制决定的。

application.yml 中配置的 spring.jackson.date-format,底层依赖的是传统的 SimpleDateFormat它只对 Java 老版本的 java.util.Date 类生效

而对于 Java 8 引入的新时间 API(如 LocalDateTimeLocalDate),Jackson 引入了一个全新的模块(JavaTimeModule)来进行处理。这个模块非常“固执”,它默认遵循严格的 ISO-8601 国际标准(即 yyyy-MM-dd'T'HH:mm:ss)。因此,它会直接无视你在 yml 里的普通日期配置。

🛠️ 解决方案

要解决这个问题,告别带 T 的日期,通常有两种方式:

方法一:局部注解配置(适合临时应对)

如果你只有极个别字段需要格式化,可以直接在实体类的字段上加上 @JsonFormat 注解。它的优先级最高,会直接接管该字段的序列化格式。

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;

public class SysUser {
    
    // ... 其他字段 ...
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
    private LocalDateTime createTime;
}

缺点:每次新建实体类都要写一遍,不仅繁琐,而且容易遗漏,不利于团队代码规范。

方法二:编写全局配置类(🌟 强烈推荐)

既然 application.yml 管不到 LocalDateTime,我们就用 Java 代码直接向 Spring Boot 的 Jackson 构建器中注入自定义的序列化规则。一劳永逸,全局生效。

在项目的 config 包下新建一个 JacksonConfig 类:

package cn.okcl.oa.config;

import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
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.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * Jackson 全局配置类
 * 解决 LocalDateTime 在 JSON 序列化时带有 'T' 的问题
 */
@Configuration
public class JacksonConfig {

    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN);
            
            // 1. 配置 LocalDateTime 的序列化(后端返回给前端的时间格式)
            builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
            
            // 2. 配置 LocalDateTime 的反序列化(前端传给后端的时间格式解析)
            builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
        };
    }
}

🎉 最终效果

加上这个配置类,重启项目后再次请求接口,你会发现 JSON 里的时间已经变成了我们最熟悉的清爽格式:

{
  "createTime": "2026-08-13 15:43:45",
  "updateTime": "2026-08-13 15:43:45"
}

补充建议:yml 中的 date-format 配置不用删除,可以继续保留。这样一来,yml 负责兜底老旧的 java.util.Date,配置类负责接管新的 LocalDateTime,双管齐下,你的项目就可以完美兼容所有的时间类型了!

SSH练手项目踩坑记录:Struts2接收OkHttp发送的JSON数据报空指针异常 2026-08-02
别让数据再“打架”了!Vue3 配合 Pinia 搞定 Tabs 标签页持久化 2026-08-16

评论区