参考学习这几个
https://blog.csdn.net/weixin_44600430/article/details/105512891
https://www.jianshu.com/p/f4654d251104
使用配置类
因为目前前后端大多是通过json格式交互。
只需要用@Configuration定义一个配置类,注入两个Bean即可完成全局日期响应格式化处理。
importcom.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;importcom.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;importorg.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;@ConfigurationpublicclassLocalDateTimeSerializerConfig{/** 注入配置文件格式化的格式
* @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
*private String pattern;
*/privatestaticfinalString YYYY_MM_DD_HH_MM_SS="yyyy-MM-dd HH:mm:ss";/**
* 注册响应json格式的LocalDateTime日期格式序列化器,指定格式
*
* @return LocalDateTimeSerializer
* @author 成大事
* @since 2022/7/23 14:16
*/@BeanpublicLocalDateTimeSerializerlocalDateTimeSerializer(){returnnewLocalDateTimeSerializer(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));}/**
* 注册json请求方式的LocalDateTime反序列化器,指定格式
*
* @return LocalDateTimeDeserializer
* @author 成大事
* @since 2022/7/23 14:16
*/@BeanpublicLocalDateTimeDeserializerlocalDateTimeDeserializer(){returnnewLocalDateTimeDeserializer(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));}/**
* 格式化日期类型,响应对应格式化日期字符串
*
* @return Jackson2ObjectMapperBuilderCustomizer
* @author 成大事
* @since 2022/7/23 14:16
*/@BeanpublicJackson2ObjectMapperBuilderCustomizerjackson2ObjectMapperBuilderCustomizer(){return builder->{//返回json格式,前端序列化为字符串
builder.serializerByType(LocalDateTime.class,localDateTimeSerializer());//从json对象日期字符串反序列化为日期对象
builder.deserializerByType(LocalDateTime.class,localDateTimeDeserializer());};}}
上面方式如果需要其他格式,那就需要配合@JsonFormat注解使用,在特定的字段属性添加@JsonFormat注解即可,因为@JsonFormat注解优先级比较高,会以@JsonFormat注解标注的时间格式为主。
使用jackson解决
JSON
请求的序列化和响应Json的反序列化, 适合前后端都是json格式交互。
根据官方文档Custom JSON Serializers and Deserializers ,想要接管Jackson
的JSON
的序列化和反序列化,只需通过注解@JsonComponent
来声明其静态内部类即可。
importcom.fasterxml.jackson.core.JsonGenerator;importcom.fasterxml.jackson.core.JsonParser;importcom.fasterxml.jackson.core.JsonProcessingException;importcom.fasterxml.jackson.databind.DeserializationContext;importcom.fasterxml.jackson.databind.JsonDeserializer;importcom.fasterxml.jackson.databind.JsonSerializer;importcom.fasterxml.jackson.databind.SerializerProvider;importorg.springframework.boot.jackson.JsonComponent;importjava.io.IOException;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.Date;@JsonComponentpublicclassDateFormatConfig{privatestaticSimpleDateFormat dateFormat=newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");/**
* 日期格式化
*/publicstaticclassDateJsonSerializerextendsJsonSerializer<Date>{@Overridepublicvoidserialize(Date date,JsonGenerator jsonGenerator,SerializerProvider serializerProvider)throwsIOException{
jsonGenerator.writeString(dateFormat.format(date));}}/**
* 解析日期字符串
*/publicstaticclassDateJsonDeserializerextendsJsonDeserializer<Date>{@OverridepublicDatedeserialize(JsonParser jsonParser,DeserializationContext deserializationContext)throwsIOException,JsonProcessingException{try{return dateFormat.parse(jsonParser.getText());}catch(ParseException e){thrownewRuntimeException(e);}}}}
GET请求及POST表单日期时间字符串格式转换
这种情况要和时间作为
Json
字符串时区别对待,因为前端json转后端entity
底层使用的是Json序列化Jackson工具(HttpMessageConverter<T>)
;而时间字符串作为普通请求参数传入时,转换用的是Converter<S, T>
,两者在处理方式上是有区别。
使用自定义参数转换器(Converter)
实现org.springframework.core.convert.converter.Converter
,自定义参数转换器,如下:
importorg.apache.commons.lang3.StringUtils;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.convert.converter.Converter;importjava.text.DateFormat;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.util.Date;@ConfigurationpublicclassDateConverterConfig{privatestaticfinalString YYYY_MM_DD="yyyy-MM-dd";privatestaticfinalString YYYY_MM_DD_HH_MM_SS="yyyy-MM-dd HH:mm:ss";/**
* 自定义类型转换,HTTP请求日期字符串转换日期类型,
* 相当于以前设置进 ConversionServiceFactoryBean
*
* @return Converter<java.lang.String,java.util.Date>
* @author 成大事
* @since 2022/7/23 14:16
*/@BeanpublicConverter<String,LocalDateTime>localDateTimeConverter(){returnnewConverter<String,LocalDateTime>(){@OverridepublicLocalDateTimeconvert(String source){try{returnparse(source);}catch(ParseException e){
e.printStackTrace();}thrownewRuntimeException("日期解析错误");}};}/**
* 根据字符串进行解析,将Date转LocalDateTime
*
* @param source 日期字符串
* @return java.time.LocalDateTime
* @author 成大事
* @since 2022/7/23 14:16
*/publicLocalDateTimeparse(String source)throwsParseException{if(StringUtils.isBlank(source)){returnnull;}DateFormat format;
source= source.trim();//判断是否yyyy-MM-dd格式if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
format=newSimpleDateFormat(YYYY_MM_DD);Date date= format.parse(source);returnLocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault());//判断是否yyyy-MM-dd HH:mm:ss格式}elseif(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
format=newSimpleDateFormat(YYYY_MM_DD_HH_MM_SS);Date date= format.parse(source);returnLocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault());}else{thrownewIllegalArgumentException("Invalid false value "+ source);}}}
以上两个bean
会注入到spring mvc
的参数解析器(好像叫做ParameterConversionService
),当传入的字符串要转为LocalDateTime
类时,spring
会调用该Converter
对这个入参进行转换。
总结一下:
我建议直接三个配置都添加。如果只是用第一个的话会发现没有转换。我的实体类的时间的Date
所以建议大家都写上