美文网首页
Spring Boot为Jackson配置日期时间格式

Spring Boot为Jackson配置日期时间格式

作者: 十毛tenmao | 来源:发表于2021-06-07 00:13 被阅读0次

Spring项目中经常需要配置日期时间格式格式,虽然可以使用@DateTimeFormatter注解配置到变量上,但是这样就需要在每个日期类上进行配置。 本文介绍兼容Date,并且兼容RequestBody和RequestParam的配置方法

设置代码

  • LocalDateTimeSerializerConfig配置日期时间格式
package com.tencent.web;

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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;

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

/**
 * 配置日期时间格式转换器.
 *
 * @author tenmao
 */
@Slf4j
@Configuration
public class LocalDateTimeSerializerConfig {
    
    /**
     * 使用这个配置,就可以兼容jackson对Date转换的格式
     */
    @Value("${spring.jackson.date-format}")
    private String pattern;

    /**
     * 定义日期时间格式.
     */
    @Bean
    public DateTimeFormatter dateTimeFormatter() {
        return DateTimeFormatter.ofPattern(pattern);
    }

    /**
     * 从日期时间格式中解析出日期格式,这样就不用再单独配置日期格式了.
     */
    @Bean
    public DateTimeFormatter dateFormatter() {
        int begin = pattern.indexOf("y");
        int end = pattern.lastIndexOf("d");
        String dateFormatter = pattern.substring(begin, end + 1);
        log.info("datetime formatter: {}, date formatter: {}", pattern, dateFormatter);
        return DateTimeFormatter.ofPattern(dateFormatter);
    }

    /**
     * 为Jackson配置LocalDateTime和LocalDate的转换规则(body).
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter()));
            builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter()));

            builder.serializerByType(LocalDate.class, new LocalDateSerializer(dateFormatter()));
            builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(dateFormatter()));
        };
    }

    /**
     * 为RequestParameter配置日期时间格式转换器.
     */
    @Bean
    public Converter<String, LocalDateTime> localDateTimeConvert() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {
                return LocalDateTime.parse(source, dateTimeFormatter());
            }
        };
    }

    /**
     * 为RequestParameter配置日期格式转换器.
     */
    @Bean
    public Converter<String, LocalDate> localDateConvert() {
        return new Converter<String, LocalDate>() {
            @Override
            public LocalDate convert(String source) {
                return LocalDate.parse(source, dateFormatter());
            }
        };
    }
}
  • @Value("${spring.jackson.date-format}")兼容了Date格式的配置信息
  • Jackson2ObjectMapperBuilderCustomizer为RequestBody和ResponseBody配置的转换格式
  • Converter<String, LocalDateTime>Converter<String, LocalDate>为RequestParam配置的转换格式
  • 还有一个小技巧就是,从{spring.jackson.date-format}解析出了日期部分的格式(没有时间),因为LocalDateTimeLocalDate不能使用同一个DateTimeFormatter

常见错误

  • Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '1998-01-02'
  • 因为还需要配置

参考

相关文章

网友评论

      本文标题:Spring Boot为Jackson配置日期时间格式

      本文链接:https://www.haomeiwen.com/subject/fvpkeltx.html