真没想到,Springboot能这样做全局日期格式化,有点香!
最近面了一些公司,有一些 Java方面的架构、面试资料,有需要的小伙伴可以在公众号【程序员内点事】里,无套路自行领取
说在前边
最近部门几位同事受了一些委屈相继离职,共事三年临别之际颇有不舍,待一切手续办妥帖,寒暄过后送他们出公司,几个老哥临别时冲我鬼魅一笑,我顿时心里一紧有种不好的预感,这事绝对没有这么简单。等我接手这几个大佬的项目后,应验了我的预感,此刻我居然有点后悔,为啥送别之时没揍他们一顿!哈哈哈~ 而这种打人的冲动,在我开始优化几位老哥的项目时候,变得越来越强烈。

有个坑
技术部每个月都会组织一下代码走查及优化,以前是各自审查优化自己的项目,如今几位老哥的离职他们的项目就落到了我的头上。对于程序员来说最痛苦的事情就是接手别人的项目,还要做优化改造,因为这一点也不比重构一遍项目简单。不过,军令在前,没办法硬着头皮上吧!
第一个优化的点就让我有点崩溃,这几个大佬的技能能力很强,一直都是我学习的榜样,但在项目里几乎所有的日期格式化都这样用 SimpleDateFormat ,像如下代码这样实现,emm~ ,受过伤的男人怎么啥事都做的出来,哈哈哈~
SvcOrderDailyStatisticsPo orderDailyStatisticsPo = new SvcOrderDailyStatisticsPo();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));
orderDailyStatisticsPo.setStatisticalDate(stationTime);
而且项目中的时间和日期API用的也比较混乱,考虑到 java.util.Date 和 java.util.Calendar 不支持时区,且非线程安全,对于日期的计算相对繁琐,技术部一致要求用JDK1.8以后的 java.time LocalDateTime。但不少人还是在用 java.util.Date 和 java.util.Calendar 处理日期。
优化方案
时间格式化是使用频率非常高的,如何让时间格式化变得既简单又不用重复造轮子,那么就应将它抽象出来,作为全局的日期格式化处理,下面就结合实践简单介绍下几种优化方案。
测试地址:http://127.0.0.1:8080/timeTest
@GetMapping("/timeTest")
public OrderInfo timeTest() {
OrderInfo order = new OrderInfo();
order.setCreateTime(LocalDateTime.now());
order.setUpdateTime(new Date());
return order;
}
1、@JsonFormat注解
使用@JsonFormat注解格式化时间,应该算是一个基本操作了,大部分开发者都应用此种方式,简单方便。
/**
* @Author: xiaofu
* @Description:
*/
public class OrderInfo {
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
测试一下结果,发现 Date 类型和 LocalDateTime 类型都格式化成功,但还是有个问题,这样做仍然比较繁琐,每个实体类的日期字段都要加@JsonFormat注解,重复的工作量也不小。接着往下看~

2、全局配置 (1)
Springboot 已经为我们提供了日期格式化 ${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss},这里我们需要进行全局配置,配置比较简单,也无需在实体类属性上添加@JsonFormat注解。
/**
* @Author: xiaofu
* @Description:
*/
public class OrderInfo {
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
只需要用@Configuration定义一个配置类,注入两个Bean即可完成全局日期格式化处理,这种方式也是当前我项目中正在用的方式。
/**
* @Author: xiaofu
* @Description:
*/
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
public LocalDateTimeSerializer localDateTimeDeserializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
}
}
这种方式可支持 Date 类型和 LocalDateTime 类型并存,那么有一个问题就是现在全局时间格式是yyyy-MM-dd HH:mm:ss,但有的字段却需要yyyy-MM-dd格式咋整?
那就需要配合@JsonFormat注解使用,在特定的字段属性添加@JsonFormat注解即可,因为@JsonFormat注解优先级比较高,会以@JsonFormat注解标注的时间格式为主。
3、全局配置 (2)
这种全局配置的实现方式与上边的效果是一样的,不过,要注意的是使用这种配置后,字段手动配置@JsonFormat注解将不再生效。
/**
* @Author: xiaofu
* @Description:
*/
public class OrderInfo {
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
/**
* @Author: xiaofu
* @Description:
*/
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
@Primary
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value.format(ofPattern(pattern)));
}
}
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {
return LocalDateTime.parse(p.getValueAsString(), ofPattern(pattern));
}
}
}
总结
分享了一个Springboot项目开发过程中的一个小技巧,也顺便吐槽一下项目优化中遇到的坑,优化别的人的代码虽然是一件比较痛苦的事情,但在这个过程中确实能学习到很多技巧,对个人的技能提升也是很有帮助,因为都是些能够实实在在提高开发效率的干货。
小福利:
几百本各类技术电子书相送 ,嘘~,免费 送给小伙伴们。关注公众号回复【666】自行领取
真没想到,Springboot能这样做全局日期格式化,有点香!的更多相关文章
- Springboot Jackson配置根本方案, 日期格式化, 时区设置生效
当项目集成配置的功能越来越多, 说不准哪个配置就影响到了什么. 比如你启用了EnableMvC, 默认配置文件配置的一些文件就失效了. 虽然约定大于配置,让springboot可以极简化构建, 但不熟 ...
- 真是没想到 Springboot + Flowable 工作流开发会这么简单
本文收录在个人博客:www.chengxy-nds.top,技术资料共享,同进步 程序员是块砖,哪里需要哪里搬 公司内部的OA系统最近要升级改造,由于人手不够就把我借调过去了,但说真的我还没做过这方面 ...
- 品Spring:真没想到,三十步才能完成一个bean实例的创建
在容器启动快完成时,会把所有的单例bean进行实例化,也可以叫做预先实例化. 这样做的好处之一是,可以及早地发现问题,及早的抛出异常,及早地解决掉. 本文就来看下整个的实例化过程.其实还是比较繁琐的. ...
- Dropbox 用什么语言开发的?(Python在各个平台都是全能的,特别是有PyObjC真没想到)
Dropbox 绝大部分是用 Python 开发的.用到 Python 的地方有:服务器后台.客户端.Dropbox 网页版前段.API 后台.数据分析. 在服务器端.桌面版客户端使用的是 Pytho ...
- 【玩转SpringBoot】翻身做主人,一统web服务器
寄人篱下的日子 一直以来受传统影响,我们的web工程总是打成war包,然后放入tomcat的webapps目录下面. 如下图01: 当tomcat启动时,会去解压war包,然后运行web工程.这大家都 ...
- 在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来
在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来 贴下课堂笔记: 在Java中使用NIO进行网络TCP套接字编程主要以下几个 ...
- 【扯淡篇】CTSC/APIO/SDOI R2时在干什么?有没有空?可以来做分母吗?
注意: 我比较弱, 并没有办法把外链bgm搞成https, 所以大家可以选择"加载不安全的脚本"或者把https改成http以获得更好的阅读体验! 据说, 退役了要写写回忆录. 但 ...
- 【原创】这道Java基础题真的有坑!我也没想到还有续集。
前情回顾 自从我上次发了<这道Java基础题真的有坑!我求求你,认真思考后再回答.>这篇文章后.我通过这样的一个行文结构: 解析了小马哥出的这道题,让大家明白了这题的坑在哪里,这题背后隐藏 ...
- 没想到 Google 排名第一的编程语言,为什么会这么火?
没想到吧,Python 又拿第一了! 在 Google 公布的编程语言流行指数中,Python 依旧是全球范围内最受欢迎的技术语言! 01 为什么 Python 会这么火? 核心还是因为企业需要用 ...
随机推荐
- pytest、tox、Jenkins实现python接口自动化持续集成
pytest介绍 pytest是一款强大的python测试工具,可以胜任各种级别的软件测试工作,可以自动查找测试用并执行,并且有丰富的基础库,可以大幅度提高用户编写测试用例的效率,具备可扩展性,用户自 ...
- 聊聊order by的工作机制
总结写在前面: 1. 介绍了orderBy的两种算法流程:全字段排序 和 rowid排序. 2. rowid排序 相比 全字段排序,参与排序字段较少,耗内存较少,多一步回表,如果内存够的情况下MySQ ...
- Vulnhub靶场 DC-2 WP
DC-2简介 描述 与DC-1一样,DC-2是另一个专门构建的易受攻击的实验室,目的是获得渗透测试领域的经验. 与原始DC-1一样,它在设计时就考虑了初学者. 必须具备Linux技能并熟悉Linux命 ...
- spring给容器中注入组件的几种方式
目录 环境搭建 spring给容器中注入组件 1.包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)适用于把自己写的类加入组件(默认ID类名 ...
- Swift 4.0 数组(Array)之过滤器(filter)的使用
我们先来定义一个常量整型数组 let array = [5, 4, 3, 1, 2] 过滤器(filter)使用之筛选出大于3的值 let resultArray = array.filter { ( ...
- XML的概述,.Dom4解析和SAX解析
1.什么是XML XML 指可扩展标记语言(EXtensible Markup Language) html(hyper text markup langauge) XML 是一种标记语言,很类似 H ...
- JavaScript 模式》读书笔记(4)— 函数1
从这篇开始,我们会用很长的章节来讨论函数,这个JavaScript中最重要,也是最基本的技能.本章中,我们会区分函数表达式与函数声明,并且还会学习到局部作用域和变量声明提升的工作原理.以及大量对API ...
- Vue中使用axios发送ajax请求
作为前后端交互的重要技巧--发送ajax请求,在Vue中我们使用axio来完成这一需求: 首先是下载axios的依赖, npm install --save axios vue-axios 然后在ma ...
- POJ1703 Find them Catch them 关于分集合操作的正确性证明 种类并查集
题目链接:http://poj.org/problem?id=1703 这道题和食物链那道题有异曲同工之处,都是要处理不同集合之间的关系,而并查集的功能是维护相同集合之间的关系.这道题中有两个不同的集 ...
- JavaWeb----Cookie&Session
## 会话技术 1.会话:一次会话中包含多次请求和响应. * 第一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止. 2.功能:再一次会话的范围内的多次请求间,共享数据 3. ...