Spring Web Jackson日期处理 - 最终篇

Spring Web Jackson日期处理 - 最终篇,第1张

之前介绍过在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日期格式配置
 *
 * 
 *     请求体、响应体JSON可通过@JsonFormat(pattern="yyyy-MM-dd")注解覆盖默认配置
 *     请求参数、请求参数对象可通过@DateTimeFormat(pattern="yyyy-MM-dd")注解覆盖默认配置
 * 
 *
 * @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.Dateyyyy-MM-dd HH:mm:ss2022-05-21 10:00:18
java.time.LocalDateyyyy-MM-dd2022-05-21
java.time.LocalDateTimeyyyy-MM-dd HH:mm:ss2022-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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1294812.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存