java开发中对于json数据中时间格式化一直都是程序员头疼的问题,这里看作者使用 @JsonComponent是怎么处理日期。另外还可以根据时区动态展示不同时间,你会了吗?
学习目标
快速学会通过注解 @JsonComponent
自定义日期格式化的序列化器。
快速查询
专题阅读:《SpringBoot 布道系列》:https://www.jianshu.com/p/964370d9374e
源码下载:SpringBoot Date Format Anno:https://github.com/yizhiwazi/springboot-socks
--- Hey Man,Don't forget to Star or Fork . ---
使用教程
首先根据项目要求提供自定义的日期序列化器和反序列化器,其中包括:
DateJsonSerializerextendsJsonSerializer<Date>
表示将Date格式化为日期字符串。DateJsonDeserializerextendsJsonDeserializer<Date>
表示将日期字符串解析为Date日期。
/**
* 全局日期格式化
*/
@JsonComponent
public class DateFormatConfig {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 日期格式化
*/
public static class DateJsonSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(dateFormat.format(date));
}
}
/**
* 解析日期字符串
*/
public static class DateJsonDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
try {
return dateFormat.parse(jsonParser.getText());
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
}
然后提供相应的测试信息,这里以查询用户为例:
/**
* 查询用户信息
*/
@RestController
public class UserController {
@GetMapping("/")
public User get() {
return new User("1", "socks", "123456", new Date(), "GMT");
}
}
/**
* 用户信息
*/
public class User {
private String userId;
private String username;
private String password;
private Date createTime;
private String timezone;
public User(String userId, String username, String password, Date createTime, String timezone) {
this.userId = userId;
this.username = username;
this.password = password;
this.createTime = createTime;
this.timezone = timezone;
}
//省略getters&setters
}
大功告成,接下来启动应用并访问 http://127.0.0.1:8080 ,可以拿到正确结果:
{
"userId": "1",
"username": "socks",
"password": "123456",
"createTime": "2018-12-26 01:03:25"
}
除了日期格式化解析之外,我们还可以在 DateFormatConfig
注入业务变量,例如根据当前登录人的所属时区(虽然 SimpleDateFormat
默认读取了当地时区,但在实际的国际化系统中,用户的所属时区是指其在系统录入的所属时区,而不是指当地时区。例如Tony这个用户账号挂在GMT+0时区,但此时他出差在香港使用,系统仍需要按照GMT+0时区来显示时间),为了解决这个问题,此时我们可以在 DateFormatConfig
注入当前登录人然后改变日期工具类的 TimeZone
来动态修改时区。
根据当前登录人动态展示时区:
/**
* 全局日期格式化
*/
@JsonComponent
public class DateFormatConfig {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z") {
@Override
public Date parse(String source) throws ParseException {
try {
if (StringUtils.isEmpty(source)) {
return null;
}
return super.parse(source);
} catch (Exception e) {
return new StdDateFormat().parse(source);
}
}
};
private static UserController userController;//这里是指获取当前登录人的工具类
@Autowired
public void setUserController(UserController userController) {
DateFormatConfig.userController = userController;
}
/**
* 日期格式化
*/
public static class DateJsonSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
//获取当前登录人的所属时区
dateFormat.setTimeZone(TimeZone.getTimeZone(userController.get().getTimezone()));
//格式化日期
jsonGenerator.writeString(dateFormat.format(date));
}
}
/**
* 解析日期字符串
*/
public static class DateJsonDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
try {
//获取当前登录人的所属时区
dateFormat.setTimeZone(TimeZone.getTimeZone(userController.get().getTimezone()));
//解析日期
return dateFormat.parse(jsonParser.getText());
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
}
修改完后重新启动应用并访问 http://127.0.0.1:8080 ,可以拿到正确结果:
{
"userId": "1",
"username": "socks",
"password": "123456",
"createTime": "2018-12-25 17:35:50 +0000",
"timezone": "GMT"
}
小结
1、使用注解 @JsonComponent
可以快速自定义日期格式化的序列化器,免除传统通过模块注册的烦恼。
2、使用注解 @JsonComponent
实现与当地无关的动态时区的精髓就在于将获取当前等人的方法写在解析日期和格式化日期的代码里。
3、使用注解 @JsonComponent
是直接处理String和Date的相互转换的,所以要注意空串问题。例如dateFormat.parse()要预防空串。
作者:yizhiwazi
https://jianshu.com/p/f4654d251104
公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!
Java精选面试题(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!
------ 特别推荐 ------
特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注。
点击“阅读原文”,了解更多精彩内容!文章有帮助的话,点在看,转发吧!