【问题背景】
昨天在联调日志列表,前端显示的日期都是时间戳格式,因为后端数据库定义的datetime类型,实体定义的date类型,以json格式返回给前端后,日期都格式化为long类型的时间戳。一看这个问题,就想到上一篇博客总结的@JsonField注解,直接利用format格式化一下,但实际情况是并没有转换。
【问题截图】
使用@JsonField字段,给前端返回的结果,还是时间戳格式。
【解决过程】
- 注解替换
项目用的是Springboot + Mybatis框架,使用@JsonField注解无效,我就查了下,有没有其他注解可以使用,查到的是jackson包下的@JsonFormat注解,所以,我就用@JsonFormat注解替换了@JsonField注解,结果是没有问题的。
- 搜索排查
使用@JsonFormat注解可以,而使用@JsonField注解不行,就开始查两个注解的区别,过程中查到一篇文章写的是@JsonFormat、@JSONField、@DateTimeFormat的使用以及其区别,其实两个注解都是可以实现日期数据格式化的,所以并不是注解使用不对的问题。紧接着换了个问题排查思路,直接查的是@JsonField注解失效原因,在这过程中,查到的更多的文章是@JsonFormat失效,但也是使用spring boot项目使用@JsonFormat无效问题这篇文章,让我找到了真正的原因。
- 真正原因
在springboot项目中,默认集成的是jackson解析json数据,并且会增加一些对应的配置,而正好,项目中也是增加了一些jackson的配置转换,代码如下:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
/**
* 序列换成json时,将所有的long变成string 因为js中得数字类型不能包含所有的java long值
*/
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(jackson2HttpMessageConverter);
}
所以,我使用@JsonFormat注解是可以将后台返回的数据格式化成对应的日期格式的。为了验证@JsonField注解也可以格式化数据,我将配置改成了阿里的fastjson,代码如下:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
// 处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastConverter.setSupportedMediaTypes(fastMediaTypes);
fastConverter.setFastJsonConfig(fastJsonConfig);
converters.add(fastConverter);
}
实体上用对应的@JsonField注解进行格式化:
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
结果和使用@JsonFormat注解一样。
- 时区问题
在此过程中,正好看到了使用@JsonFormat注解会有8小时时差问题,原因是没有设置时区。
@JsonFormat注解的用法:
在属性值上 @JsonFormat(pattern=”yyyy-MM-dd”,timezone=”GMT+8”),如果直接使用 @JsonFormat(pattern=”yyyy-MM-dd”)就会出现2018-08-01 08:00:00的情况, 会相差8个小时,因为我们是东八区(北京时间)。所以我们在格式化的时候要指定时区(timezone )
【总结】
多思考几个为什么,总是会有收获的。