java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot全局日期格式配置

SpringBoot全局日期格式配置的方法总结

作者:BillKu

本文介绍了在SpringBoot中避免在每个实体类中重复设置@JsonFormat注解的几种方法,包括全局配置、自定义Jackson配置类、使用Mixin、自定义注解等,推荐使用全局配置,可以简化代码并满足大部分场景,需要的朋友可以参考下
spring boot中,不想每个实体类中都这样设置,有什么方法:
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

在Spring Boot中有几种方法可以避免在每个实体类中重复设置@JsonFormat注解:

方法一:全局配置(推荐)

application.ymlapplication.properties中配置全局的日期格式:

YAML配置:

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-dates-as-timestamps: false

Properties配置:

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-dates-as-timestamps=false

方法二:自定义Jackson配置类

@Configuration
public class JacksonConfig {
    
    @Bean
    @Primary
    public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            // 设置全局日期格式
            builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
            builder.timeZone(TimeZone.getTimeZone("GMT+8"));
            
            // 针对Java 8时间API的配置
            builder.serializers(new LocalDateTimeSerializer(
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            builder.deserializers(new LocalDateTimeDeserializer(
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            
            // 如果需要,也可以配置LocalDate等其他类型
            builder.serializers(new LocalDateSerializer(
                DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            builder.deserializers(new LocalDateDeserializer(
                DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        };
    }
}

方法三:更详细的配置类

@Configuration
public class JacksonConfig {
    
    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        
        // 设置Java 8时间模块
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        
        // LocalDateTime序列化和反序列化
        javaTimeModule.addSerializer(LocalDateTime.class, 
            new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDateTime.class,
            new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        
        // LocalDate序列化和反序列化
        javaTimeModule.addSerializer(LocalDate.class,
            new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addDeserializer(LocalDate.class,
            new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        
        objectMapper.registerModule(javaTimeModule);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        
        return objectMapper;
    }
}

方法四:使用Mixin(为特定类型统一配置)

@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
abstract class LocalDateTimeMixin {
}

@Configuration
public class JacksonConfig {
    
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer addCustomSerialization() {
        return builder -> {
            builder.mixIn(LocalDateTime.class, LocalDateTimeMixin.class);
        };
    }
}

方法五:自定义注解(如果需要不同格式)

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public @interface DefaultDateTimeFormat {
}

// 使用方式
@DefaultDateTimeFormat
private LocalDateTime createTime;

推荐方案

建议使用方法一(全局配置),最简单直接,能满足大部分场景。

如果项目中有多种不同的日期格式需求,可以:

  1. 使用方法一设置默认格式
  2. 对于特殊格式的字段,使用@JsonFormat覆盖全局配置
// 全局使用 yyyy-MM-dd HH:mm:ss
// 特殊字段使用其他格式
@JsonFormat(pattern = "yyyy/MM/dd")
private LocalDate specialDate;

这样既能减少重复代码,又能保持灵活性。

已经设置日期格式:
  jackson:
    # 全局配置日期格式,这样就不用每个实体类的日期属性使用 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-dates-as-timestamps: false
    deserialization:
      adjust-dates-to-context-time-zone: false
 
package com.weiyu.model;
 
import lombok.Data;
 
import java.time.LocalDateTime;
 
/**
 * 打印模板列表 VO
 */
@Data
public class PrintTemplateListVO {
    private Integer id;
    private String templateType;
    private String templateName;
    private String templateCode;
    private String printDirection;
    private Boolean enabled;
    private String createBy;
    private LocalDateTime createTime;
    private String updateBy;
    private LocalDateTime updateTime;
}
 
但是为什么前端显示的日期内容是:2025-12-19T16:17:32.717

这是因为全局配置的 date-format 只对 java.util.Date 类型有效,对于 Java 8 的 LocalDateTime 类型不生效。需要单独配置 Java 8 时间模块。

解决方案:

方案一:创建 Jackson 配置类(推荐)

import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

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

@Configuration
public class JacksonConfig {

    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    @Bean
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
        return new Jackson2ObjectMapperBuilder()
            .modulesToInstall(new JavaTimeModule())
            .serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)))
            .deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)))
            .simpleDateFormat(DATE_TIME_FORMAT)
            .timeZone(java.util.TimeZone.getTimeZone("GMT+8"));
    }
}

方案二:更完整的配置类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

@Configuration
public class JacksonConfig {

    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    @Bean
    @Primary
    public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            // 配置 Java 8 时间模块
            builder.modulesToInstall(new JavaTimeModule());
            
            // 配置 LocalDateTime 的序列化和反序列化
            builder.serializers(new LocalDateTimeSerializer(
                DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
            builder.deserializers(new LocalDateTimeDeserializer(
                DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
            
            // 其他配置
            builder.simpleDateFormat(DATE_TIME_FORMAT);
            builder.timeZone(TimeZone.getTimeZone("GMT+8"));
            builder.featuresToDisable(
                com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
            );
        };
    }
}

方案三:完整的 ObjectMapper Bean

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

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

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        
        // 配置 LocalDateTime
        javaTimeModule.addSerializer(LocalDateTime.class, 
            new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDateTime.class,
            new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        
        mapper.registerModule(javaTimeModule);
        mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        mapper.setTimeZone(java.util.TimeZone.getTimeZone("GMT+8"));
        
        return mapper;
    }
}

方案四:添加依赖(如果未添加)

确保你的 pom.xml 中包含 Jackson Java 8 时间模块的依赖:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

验证配置

添加配置后,LocalDateTime 字段应该会正确格式化为 "2025-12-19 16:17:32",而不是 "2025-12-19T16:17:32.717"

为什么需要单独配置?

建议使用方案一,它比较简洁且能解决问题。配置后不需要在每个实体类中添加 @JsonFormat 注解。

代码实例:

package com.weiyu.config;

import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.time.format.DateTimeFormatter;

/**
 * Jackson JSON 序列化/反序列化全局配置类
 * <p>
 * 作用:统一配置项目中日期时间类型的 JSON 格式化方式
 * 解决:LocalDateTime 等 Java 8 时间类型在前端显示为 ISO 格式(如:2025-12-19T16:17:32.717)的问题
 * 效果:所有 LocalDateTime 字段将统一格式化为 "yyyy-MM-dd HH:mm:ss"
 * <p>
 * 配置效果总结:
 * 1. 序列化(对象 → JSON):
 * - LocalDateTime: 格式化为 "yyyy-MM-dd HH:mm:ss"
 * - java.util.Date: 格式化为 "yyyy-MM-dd HH:mm:ss"
 * - 其他 Java 8 时间类型(LocalDate、LocalTime):使用默认格式
 * <p>
 * 2. 反序列化(JSON → 对象):
 * - 能正确解析 "yyyy-MM-dd HH:mm:ss" 格式的字符串为 LocalDateTime
 * - 也支持其他常见日期格式
 * <p>
 * 3. 优势:
 * - 无需在每个实体类的字段上添加 @JsonFormat 注解
 * - 统一整个项目的日期时间格式
 * - 同时支持新旧日期 API(java.util.Date 和 java.time)
 * <p>
 * 4. 注意事项:
 * - 如果某个字段需要特殊格式,仍可使用 @JsonFormat 覆盖此全局配置
 * - 此配置不会影响数据库存储,仅影响 JSON 序列化/反序列化
 */
@Configuration  // 声明这是一个 Spring 配置类,Spring 启动时会自动扫描并加载
public class JacksonConfig {

    /**
     * 从 application.yml 中读取日期格式配置
     * 使用默认值:如果配置文件中没有 spring.jackson.date-format,则使用 "yyyy-MM-dd HH:mm:ss"
     */
    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String dateFormat;

    /**
     * 从 application.yml 中读取时区配置
     * 使用默认值:如果配置文件中没有 spring.jackson.time-zone,则使用 "Asia/Shanghai"
     */
    @Value("${spring.jackson.time-zone:Asia/Shanghai}")
    private String timeZone;

    /**
     * 创建并配置 Jackson2ObjectMapperBuilder Bean
     * <p>
     * 这个方法返回的 Jackson2ObjectMapperBuilder 会被 Spring 用于创建所有 ObjectMapper 实例
     * 包括 REST Controller 返回 JSON 时使用的 ObjectMapper
     *
     * @return 配置好的 Jackson2ObjectMapperBuilder 实例
     */
    @Bean  // 声明这是一个 Spring Bean,Spring 容器会管理它的生命周期
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
        // 使用 Builder 模式链式配置 Jackson
        return new Jackson2ObjectMapperBuilder()
                // 1. 安装 JavaTimeModule 模块
                //    作用:让 Jackson 支持 Java 8 的时间类型(LocalDateTime、LocalDate、LocalTime等)
                //    如果没有这个模块,Jackson 无法正确处理 Java 8 时间类型
                .modulesToInstall(new JavaTimeModule())

                // 2. 配置序列化器
                //    作用:将 LocalDateTime、LocalDate、LocalTime 对象转换为 JSON 字符串时使用的格式化规则
                //    示例:LocalDateTime.now() → "2025-12-19 16:17:32"
                .serializers(
                        new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateFormat)),
                        new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
                        new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))
                )

                // 3. 配置反序列化器
                //    作用:将 JSON 字符串转换为 LocalDateTime 对象时使用的解析规则
                //    示例:"2025-12-19 16:17:32" → LocalDateTime、LocalDate、LocalTime 对象
                .deserializers(
                        new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(dateFormat)),
                        new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
                        new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))
                )

                // 4. 配置传统 java.util.Date 类型的日期格式
                //    作用:传统 Date 类型也使用相同的日期格式
                //    兼容性:确保项目中既有 java.util.Date 也有 java.time 类型时,格式保持一致
                .simpleDateFormat(dateFormat)

                // 5. 配置时区
                //    作用:设置序列化和反序列化时的默认时区
                //    重要:时区设置会影响日期时间的显示和解析
                //    "Asia/Shanghai" - 中国标准时间(UTC+8)
                //    注意:LocalDateTime 不包含时区信息,此设置主要影响 Date 和 Instant 类型
                .timeZone(java.util.TimeZone.getTimeZone(timeZone));
    }
}

以上就是SpringBoot全局日期格式配置的方法总结的详细内容,更多关于SpringBoot全局日期格式配置的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文