springboot 版本2.0.4,针对全局的日期出入参做一个详细的配置介绍,局部日期转换可采用@JsonFormat注解实现,本文不再赘述。
1.自定义日期入参
对于表单参数或get请求url后面跟着的日期入参,通过装配以下配置来实现日期入参转换:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
}
}
意思就是入参可传入yyyy-MM-dd HH:mm:ss格式的日期,框架会自动将该字符串映射到对应的Date入参字段上,例如http://localhost:8080/test?startTime=2019-06-27 10:59:59,后台会用Date startTime字段接收这个入参。
注意:startTime=2019-06-27 或 startTime=1561605650476等不满足的格式都会报错,另外,
通过继承的方式即extends WebMvcConfigurationSupport会导致autoConfig失效,可以通过implements WebMvcConfigurer的方式
假设前端入参传的是时间戳后端如何处理呢?
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new Long2DateConverter());
}
public class Long2DateConverter implements Converter<String, Date> {
@Override
public Date convert(String ts) {
if (ts == null) {
return null;
}
return new Date(Long.valueOf(ts));
}
}
}
此时需要自己实现一个转换器,注意,时间戳虽然在后端看来是个long类型,但是前端传过来依然是个String,所以转换器是从String->Date,而不能写Long->Date,否则会报错。
好了,上述方法只适用于表单参数和url参数,而json入参需要通过配置jackson来生效。
2.自定义出参
springboot默认采用的是jackson进行json转换,本文只阐述使用jackson的方式配置日期参数。
此处只介绍使用yml配置的方式,使用properties文件方式类似。配置如下:
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write_dates_as_timestamps: false
对于json入参而言,需要满足yyyy-MM-dd HH:mm:ss格式才能正常转换,但实践发现,入参如果为时间戳也能自动转换(这里没有找到原因,毕竟没有看过源码),
对于json出参而言,日期返回到前端是yyyy-MM-dd HH:mm:ss格式的字符串。
另外,write_dates_as_timestamps属性决定返回的日期是否会被转换为时间戳,该属性默认为true,不配置该属性默认返回时间戳。
值得注意的是,write_dates_as_timestamps属性是归属于serialization属性下,即序列化属性,序列化的意思是代表从java对象->json串,也就是只作用于出参。所以该属性对入参无效。
3.总结
由于笔者并未阅读过springboot相关源码,所以以上阐述都是根据实际经验总结出来,只讨论怎么用,不深究为什么。
- 对于form表单参数或url参数的日期格式,需要在implements WebMvcConfigurer的配置类中进行注册。两种方式:registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));和registry.addConverter(new Long2DateConverter());实现对标准日期串和时间戳入参的绑定;
- jackson配置同时作用于json格式的日期入参和出参,标准日期串方式date-format: yyyy-MM-dd HH:mm:ss,write_dates_as_timestamps: false。时间戳方式write_dates_as_timestamps: true或不配置该属性