Spring Web Jackson日期处理 - 最终篇

之前介绍过在Spring Web中如何处理Java日期格式,可参见我之前的文章:
《SpringBoot Web Java8日期处理》
今天给出一个最终的解决方案,通过一个配置类可以同时设置Web接收参数、输出结果中的日期格式,
同时支持java.util.Date和Java8+ java.time.*。

配置定义

首先定义配置属性类:

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Jackson配置属性
 *
 * @author luohq
 * @version 1.0.0
 * @date 2022-05-17 10:36
 */
@ConfigurationProperties(prefix = WebJacksonProps.PREFIX)
public class WebJacksonProps {
    /**
     * 属性配置前缀
     */
    public static final String PREFIX = "web.jackson";
    /**
     * 默认日期格式定义
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_LOCAL_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_LOCAL_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_TIME_ZONE = "GMT+8";

    /**
     * 是否启用Osmium Jackson配置
     */
    private Boolean enabled = true;
    /**
     * 日期格式 - java.util.Date
     */
    private String dateFormat = DEFAULT_DATE_FORMAT;
    /**
     * 日期格式 - java.time.LocalDate
     */
    private String localDateFormat = DEFAULT_LOCAL_DATE_FORMAT;
    /**
     * 日期时间格式 - java.time.LocalDateTime
     */
    private String localDateTimeFormat = DEFAULT_LOCAL_DATE_TIME_FORMAT;
    /**
     * 时区
     */
    private String timeZone = DEFAULT_TIME_ZONE;

    //省略getter/setter
}

然后定义配置类:

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.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.datetime.DateFormatterRegistrar;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

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

/**
 * Jackson日期格式配置
 *
 * 
    *
  1. 请求体、响应体JSON可通过@JsonFormat(pattern="yyyy-MM-dd")注解覆盖默认配置
  2. *
  3. 请求参数、请求参数对象可通过@DateTimeFormat(pattern="yyyy-MM-dd")注解覆盖默认配置
  4. *
* * @author luohq * @date 2022-05-17 10:33 */
@Configuration @EnableConfigurationProperties({WebJacksonProps.class}) @ConditionalOnProperty(prefix = WebJacksonProps.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) public class WebJacksonConfiguration implements WebMvcConfigurer { /** * Web Jackson配置属性 */ private WebJacksonProps webJacksonProps; public WebJacksonConfiguration(WebJacksonProps webJacksonProps) { this.webJacksonProps = webJacksonProps; } /** * Json请求体、响应体 - 日期序列化配置 */ @Bean public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { return builder -> { //java.util.Date日期格式 builder.simpleDateFormat(this.webJacksonProps.getDateFormat()); //Java8+ java.time.*日期格式 DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern(this.webJacksonProps.getLocalDateFormat()) .withZone(ZoneId.of(this.webJacksonProps.getTimeZone())); DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern(this.webJacksonProps.getLocalDateTimeFormat()) .withZone(ZoneId.of(this.webJacksonProps.getTimeZone())); builder.serializers(new LocalDateSerializer(localDateFormatter)); builder.serializers(new LocalDateTimeSerializer(localDateTimeFormatter)); builder.deserializers(new LocalDateDeserializer(localDateFormatter)); builder.deserializers(new LocalDateTimeDeserializer(localDateTimeFormatter)); }; } /** * 请求参数 - 日期格式化转换配置 */ @Override public void addFormatters(FormatterRegistry registry) { //java.util.Date日期格式 DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar(); DateFormatter dateFormatter = new DateFormatter(this.webJacksonProps.getDateFormat()); dateFormatter.setTimeZone(TimeZone.getTimeZone(this.webJacksonProps.getTimeZone())); dateRegistrar.setFormatter(dateFormatter); dateRegistrar.registerFormatters(registry); //Java8+ java.time.*日期格式 DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar(); dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern(this.webJacksonProps.getLocalDateFormat()) .withZone(ZoneId.of(this.webJacksonProps.getTimeZone()))); dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern(this.webJacksonProps.getLocalDateTimeFormat()) .withZone(ZoneId.of(this.webJacksonProps.getTimeZone()))); dateTimeRegistrar.registerFormatters(registry); } }

使用方式

在Spring Boot Web环境中保证如上配置类WebJacksonConfiguration被扫描加载即可,
默认日期格式如下:

Java类型 默认格式 示例值
java.util.Date yyyy-MM-dd HH:mm:ss 2022-05-21 10:00:18
java.time.LocalDate yyyy-MM-dd 2022-05-21
java.time.LocalDateTime yyyy-MM-dd HH:mm:ss 2022-05-21 10:00:18

亦可通过如下配置修改默认日期格式:

web:
  jackson:
    # Date格式
    date-format: yyyy-MM-dd HH:mm:ss
    # LocalDate格式
    local-date-format: yyyy-MM-dd
    # LocalDateTime格式
    local-date-time-format: yyyy-MM-dd HH:mm:ss
    # 时区
    time-zone: GMT+8

同时:

  • 请求体@RequestBody、响应体@ResponseBody 可通过@JsonFormat(pattern=“yyyy-MM-dd”)注解覆盖默认日期格式
  • 请求参数@RequestParam、请求参数对象可通过@DateTimeFormat(pattern=“yyyy-MM-dd”)注解覆盖默认日期格式

参考:
https://www.baeldung.com/spring-date-parameters
https://www.baeldung.com/spring-boot-formatting-json-dates

你可能感兴趣的:(#,springboot,spring,jackson,date,java8)