Spring Boot为Jackson配置日期时间格式
2021-06-07 本文已影响0人
十毛tenmao
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}
解析出了日期部分的格式(没有时间),因为LocalDateTime
和LocalDate
不能使用同一个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'
- 因为还需要配置