当前位置:网站首页>关于LocalDateTime的全局返回时间带“T“的时间格式处理
关于LocalDateTime的全局返回时间带“T“的时间格式处理
2022-07-31 05:08:00 【m0_67401920】
关于LocalDateTime的全局返回带"T"的时间格式处理
关于背景的大概描述,如下。
时间类型LocalDateTime相较于于Date的确有自己独特的优势,因此在之后的版本迭代上,将部分隔离开的模块使用了新型的LocalDateTime替代了Date,因已经使用了全局时间转换,但是测试的时候发现返回的时间格式很奇怪 2022-01-01T00:00:00.000,全局时间序列化、反序列化并没有起作用,寻找相关资料和DEGBU之后将相关资料整理如下。
目前常用的时间类型格式如下:
时间类型
时间默认格式
Date
Tue Feb 01 00:00:00 CST 2022
Timestamp
2022-01-01 00:00:00.0
LocalDateTime
2022-01-01T00:00:00.000
1.关于jackson的全局返回带T的处理方式
对于Date和Timestamp在引入LocalDateTime之前是经过spring.jackson.date-format进行全局数据绑定格式化时间类型。
spring:
jackson:
date-format: 格式化类
在格式化类中添加对LocalDateTime的格式化语句发现无效果。经过搜索资料后发现在使用jackson在对localDateTime类型的序列化和反序列化方法另有其他方法。(这里不输出关于源码内的信息。可自行查看。)
// 涉及源码类 其余的可自行debug追踪
Jackson2ObjectMapperBuilder
Jackson2ObjectMapperBuilderCustomizer // 最终做处理的服务类
JacksonAutoConfiguration
@Configuration
public class LocalDateTimeSerializerConfig {
// jackson注册的时候会将序列化和反序列化的方法提前注册进,做数据转换会自行根据具体的实现去调用。
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer());
};
}
/**
* 反序列化
*/
public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
throws IOException {
long timestamp = p.getValueAsLong();
if (timestamp > 0) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
} else {
return null;
}
}
}
}
2.关于fastjson的全局返回带T的处理方式
使用fastjson进行时间格式化处理,自己写的类去实现 WebMvcConfigurer配置类,重写父类方法configureMessageConverters,在进行全局时间返回格式绑定后,之前使用的格式化时间类是fastjson自身提供的SimpleDateFormatSerializer方法,发现在进行对LocalDateTime添加后进行时间转化返回后存在异常,异常信息提示LocalDateTime不能强转为Date,进行多次DEBUG跟踪后定位到了SimpleDateFormatSerializer方法内部,会将拿到的value直接进行Date的强转,SimpleDateFormatSerializer源码如下
public class SimpleDateFormatSerializer implements ObjectSerializer {
private final String pattern;
public SimpleDateFormatSerializer(String pattern){
this.pattern = pattern;
}
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
if (object == null) {
serializer.out.writeNull();
return;
}
// 对LocalDateTime 进行强制转换,此处会报错。因此,主要的重点改造就是此处。
Date date = (Date) object;
SimpleDateFormat format = new SimpleDateFormat(pattern, serializer.locale);
format.setTimeZone(serializer.timeZone);
String text = format.format(date);
serializer.write(text);
}
}
既然已经发现问题的关键点那对关键点进行处理即可,目前有两个方法:
- 写好SimpleDateFormatSerializer的继承类
- 实现ObjectSerializer的write方法进行处理。
我选用的是第一种方式对SimpleDateFormatSerializer集成后重写write方法,因为之前的时间格式已经使用的SimpleDateFormatSerializer进行处理,为了稳定进行最小程度的调整。结果如下
public class OwnSimpleDateFormatSerializer extends SimpleDateFormatSerializer {
private final String pattern;
public OwnSimpleDateFormatSerializer (String pattern) {
super(pattern);
this.pattern = pattern;
}
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
if (object == null) {
serializer.out.writeNull();
} else {
Date date = null;
// 改造内容 增加类型判断进行处理
if (object instanceof LocalDateTime) {
LocalDateTime localDateTime = (LocalDateTime) object;
date = Date.from(localDateTime.atZone( ZoneId.systemDefault()).toInstant());
} else {
date = (Date)object;
}
SimpleDateFormat format = new SimpleDateFormat(this.pattern, Locale.SIMPLIFIED_CHINESE);
TimeZone timeZone = new ZoneInfo();
timeZone.setRawOffset(28800000);
timeZone.setID("Asia/Shanghai");
format.setTimeZone(timeZone);
String text = format.format(date);
serializer.write(text);
}
}
}
// 涉及类
WebMvcConfigurer
SimpleDateFormatSerializer // 之前使用的时间格式化类
ObjectSerializer // 最终执行时间格式化处理的服务类
FastJsonConfig // 配置类
SerializeConfig // 序列化配置信息
@Component
public class DefaultMvcFilter implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// ...
// 重点在此 对FastJsonConfig进行配置
FastJsonConfig fastJsonConfig = new FastJsonConfig();
// 修改全局json配置
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
// 格式化时间
serializeConfig.put(Date.class, new OwnSimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
serializeConfig.put(java.sql.Date.class, new OwnSimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
serializeConfig.put(java.sql.Timestamp.class, new OwnSimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
serializeConfig.put(java.sql.Time.class, new OwnSimpleDateFormatSerializer("HH:mm:ss"));
// 对LocalDateTime进行时间格式化 注意序列化的实现类 是需要自己写的,并不是使用fastjson自带的SimpleDateFormatSerializer
serializeConfig.put(LocalDateTime.class, new OwnSimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastJsonConfig.setSerializeConfig(serializeConfig);
fastJsonConfig.setSerializerFeatures(
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.IgnoreErrorGetter,
SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.WriteNullBooleanAsFalse,
SerializerFeature.DisableCircularReferenceDetect
);
}
}
以上对于jackson和fastjson改造完成后进行测试,发现时间格式全部展示正确,以此来记录问题发生和处理方式。主要还是根据源码跟踪来确定问题,问题确定后的处理就会有很多方式了,选择最适用的处理方式即可。
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
- 1. 获取数据-requests.get()
- Unity Framework Design Series: How Unity Designs Network Frameworks
- matlab abel变换图片处理
- 精解四大集合框架:List 核心知识总结
- STM32——DMA
- MySQL database installation (detailed)
- matlab simulink欠驱动水面船舶航迹自抗扰控制研究
- MYSQL下载及安装完整教程
- .NET-6.WinForm2.NanUI学习和总结
- ERROR 2003 (HY000) Can't connect to MySQL server on 'localhost3306' (10061)
猜你喜欢
随机推荐
ERP Production Operation Control Kingdee
参考代码系列_1.各种语言的Hello World
剑指offer专项突击版第15天
.NET-6.WinForm2.NanUI learning and summary
Tapdata 与 Apache Doris 完成兼容性互认证,共建新一代数据架构
三道leetcode上的oj题
太厉害了,终于有人能把文件上传漏洞讲的明明白白了
MySQL8.0.26安装配置教程(windows 64位)
[py script] batch binarization processing images
MySQL database installation (detailed)
MySQL(更新中)
Shell重油常压塔模拟仿真与控制
Unity手机游戏性能优化系列:针对CPU端的性能调优
Numpy中np.meshgrid的简单用法示例
Go language study notes - dealing with timeout problems - Context usage | Go language from scratch
MySQL optimization slow log query
益智类游戏关卡设计:逆推法--巧解益智类游戏关卡设计
MySQL forgot password
Doris学习笔记之监控
mysql stored procedure









