当前位置:网站首页>关于LocalDateTime的全局返回时间带“T“的时间格式处理
关于LocalDateTime的全局返回时间带“T“的时间格式处理
2022-08-01 16:57:00 【m0_61083409】
关于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开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
- 金仓数据库 KingbaseES V8.3 至 V8.6 迁移最佳实践(4. V8.3 到 V8.6 数据库移植实战)
- 年化收益高的理财产品
- 短剧正在抢长剧的生意
- Winform message prompt box helper class
- MUI as a mobile phone to return to the action bar
- 在码云拉取代码后,调整了seata版本1.5.2。出现如下异常。是因为数据库表缺少字段导致的吗?
- C#Excel帮助类
- 变量交换;复合赋值;增递减运算符
- GridControl helper class for DevExpress
- 网上开户佣金万一靠谱吗,网上开户安全吗
猜你喜欢

Description of common operations and help projects about DevExpress in C#

AntDB数据库亮相24届高速展,助力智慧高速创新应用

MLX90640 红外热成像仪测温模块开发笔记(完整版)

缓存一致性MESI与内存屏障

谁还敢买影视股?

70后夫妻给苹果华为做“雨衣”,三年进账7.91亿

Bugku-Misc-贝斯手

Rancher 部署 DataKit 最佳实践

Vulnhub target drone: HARRYPOTTER_ NAGINI

Ali's official Redis development specification
随机推荐
如何有效地开发 Jmix 扩展组件
【R语言】对图片进行裁剪 图片批量裁剪
LeetCode第 303 场周赛
【建议收藏】技术面必考题:多线程、多进程
Ali's official Redis development specification
好家伙,公司服务器直接热崩掉了!
棕榈油罐区数字化转型
软测面试如何介绍项目?要做哪些技术准备?
Description of common operations and help projects about DevExpress in C#
自定义注解实现日志打印时屏蔽特定字段不打印
【TDP加码福利】COS用户实践征文月,等你来投稿!!!
2022年深圳市临床医学研究中心申请指南
ROS2系列知识(7):用rqt_console查看日志logs
【R语言】线性混合模型进行重复测量设计分析
Flask框架实战
金仓数据库 MySQL 至 KingbaseES 迁移最佳实践(2. 概述)
晶振工作原理详解
2022 Strong Net Cup CTF---Strong Net Pioneer ASR wp
2022强网杯CTF---强网先锋 ASR wp
工业制造行业的低代码开发平台思维架构图