Springboot 全局日期格式化處理的實(shí)現(xiàn)
最近部門幾位同事受了一些委屈相繼離職,共事三年臨別之際頗有不舍,待一切手續(xù)辦妥帖,寒暄過(guò)后送他們出公司,幾個(gè)老哥臨別時(shí)沖我鬼魅一笑,我頓時(shí)心里一緊有種不好的預(yù)感,這事絕對(duì)沒(méi)有這么簡(jiǎn)單。等我接手這幾個(gè)大佬的項(xiàng)目后,應(yīng)驗(yàn)了我的預(yù)感,此刻我居然有點(diǎn)后悔,為啥送別之時(shí)沒(méi)揍他們一頓!哈哈哈~ 而這種打人的沖動(dòng),在我開(kāi)始優(yōu)化幾位老哥的項(xiàng)目時(shí)候,變得越來(lái)越強(qiáng)烈。

有個(gè)坑
技術(shù)部每個(gè)月都會(huì)組織一下代碼走查及優(yōu)化,以前是各自審查優(yōu)化自己的項(xiàng)目,如今幾位老哥的離職他們的項(xiàng)目就落到了我的頭上。對(duì)于程序員來(lái)說(shuō)最痛苦的事情就是接手別人的項(xiàng)目,還要做優(yōu)化改造,因?yàn)檫@一點(diǎn)也不比重構(gòu)一遍項(xiàng)目簡(jiǎn)單。不過(guò),軍令在前,沒(méi)辦法硬著頭皮上吧!
第一個(gè)優(yōu)化的點(diǎn)就讓我有點(diǎn)崩潰,這幾個(gè)大佬的技能能力很強(qiáng),一直都是我學(xué)習(xí)的榜樣,但在項(xiàng)目里幾乎所有的日期格式化都這樣用 SimpleDateFormat ,像如下代碼這樣實(shí)現(xiàn),emm~ ,受過(guò)傷的男人怎么啥事都做的出來(lái),哈哈哈~
SvcOrderDailyStatisticsPo orderDailyStatisticsPo = new SvcOrderDailyStatisticsPo();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));
orderDailyStatisticsPo.setStatisticalDate(stationTime);
而且項(xiàng)目中的時(shí)間和日期API用的也比較混亂,考慮到 java.util.Date 和 java.util.Calendar 不支持時(shí)區(qū),且非線程安全,對(duì)于日期的計(jì)算相對(duì)繁瑣,技術(shù)部一致要求用JDK1.8以后的 java.time LocalDateTime。但不少人還是在用 java.util.Date 和 java.util.Calendar 處理日期。
優(yōu)化方案
時(shí)間格式化是使用頻率非常高的,如何讓時(shí)間格式化變得既簡(jiǎn)單又不用重復(fù)造輪子,那么就應(yīng)將它抽象出來(lái),作為全局的日期格式化處理,下面就結(jié)合實(shí)踐簡(jiǎn)單介紹下幾種優(yōu)化方案。
測(cè)試地址: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注解格式化時(shí)間,應(yīng)該算是一個(gè)基本操作了,大部分開(kāi)發(fā)者都應(yīng)用此種方式,簡(jiǎn)單方便。
/**
* @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;
}
}
測(cè)試一下結(jié)果,發(fā)現(xiàn) Date 類型和 LocalDateTime 類型都格式化成功,但還是有個(gè)問(wèn)題,這樣做仍然比較繁瑣,每個(gè)實(shí)體類的日期字段都要加@JsonFormat注解,重復(fù)的工作量也不小。接著往下看~

2、全局配置 (1)
Springboot 已經(jīng)為我們提供了日期格式化 ${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss},這里我們需要進(jìn)行全局配置,配置比較簡(jiǎn)單,也無(wú)需在實(shí)體類屬性上添加@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定義一個(gè)配置類,注入兩個(gè)Bean即可完成全局日期格式化處理,這種方式也是當(dāng)前我項(xiàng)目中正在用的方式。
/**
* @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 類型并存,那么有一個(gè)問(wèn)題就是現(xiàn)在全局時(shí)間格式是yyyy-MM-dd HH:mm:ss,但有的字段卻需要yyyy-MM-dd格式咋整?
那就需要配合@JsonFormat注解使用,在特定的字段屬性添加@JsonFormat注解即可,因?yàn)?code>@JsonFormat注解優(yōu)先級(jí)比較高,會(huì)以@JsonFormat注解標(biāo)注的時(shí)間格式為主。
3、全局配置 (2)
這種全局配置的實(shí)現(xiàn)方式與上邊的效果是一樣的,不過(guò),要注意的是使用這種配置后,字段手動(dòng)配置@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));
}
}
}
總結(jié)
分享了一個(gè)Springboot項(xiàng)目開(kāi)發(fā)過(guò)程中的一個(gè)小技巧,也順便吐槽一下項(xiàng)目?jī)?yōu)化中遇到的坑,優(yōu)化別的人的代碼雖然是一件比較痛苦的事情,但在這個(gè)過(guò)程中確實(shí)能學(xué)習(xí)到很多技巧,對(duì)個(gè)人的技能提升也是很有幫助,因?yàn)槎际切┠軌驅(qū)崒?shí)在在提高開(kāi)發(fā)效率的干貨。
到此這篇關(guān)于Springboot 全局日期格式化處理的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Springboot 全局日期格式化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot實(shí)現(xiàn)設(shè)置全局和局部時(shí)間格式化
- Springboot 全局時(shí)間格式化操作
- SpringBoot JSON全局日期格式轉(zhuǎn)換器實(shí)現(xiàn)方式
- springboot全局日期格式化的兩種方式
- SpringBoot中?Jackson?日期的時(shí)區(qū)和日期格式問(wèn)題解決
- SpringBoot中Jackson日期格式化技巧分享
- SpringBoot利用jackson格式化時(shí)間的三種方法
- SpringBoot2.0整合jackson配置日期格式化和反序列化的實(shí)現(xiàn)
- SpringBoot使用Jackson配置全局時(shí)間日期格式
相關(guān)文章
Java Web項(xiàng)目創(chuàng)建并實(shí)現(xiàn)前后端交互
本文主要介紹了Java Web項(xiàng)目創(chuàng)建并實(shí)現(xiàn)前后端交互,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Spring實(shí)現(xiàn)上拉刷新和下拉加載效果
這篇文章主要為大家詳細(xì)介紹了Spring實(shí)現(xiàn)上拉刷新和下拉加載效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
一文帶你深入理解Java?AbstractQueuedSynchronizer
在并發(fā)編程中,鎖是一種保證線程安全的方式,這篇文章主要為大家介紹了AbstractQueuedSynchronizer(AQS)的數(shù)據(jù)結(jié)構(gòu)及實(shí)現(xiàn)原理,感興趣的小伙伴可以了解一下2023-07-07
面試官:java ThreadLocal真的會(huì)造成內(nèi)存泄露嗎
ThreadLocal,java面試過(guò)程中的“釘子戶”,在網(wǎng)上也充斥著各種有關(guān)ThreadLocal內(nèi)存泄露的問(wèn)題,本文換個(gè)角度,先思考ThreadLocal體系中的ThreadLocalMap為什么要設(shè)計(jì)成弱引用2021-08-08
java使用動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)AOP(日志記錄)的實(shí)例代碼
AOP(面向方面)的思想,就是把項(xiàng)目共同的那部分功能分離開(kāi)來(lái),比如日志記錄,避免在業(yè)務(wù)邏輯里面夾雜著跟業(yè)務(wù)邏輯無(wú)關(guān)的代碼2013-09-09
java ThreadPool線程池的使用,線程池工具類用法說(shuō)明
這篇文章主要介紹了java ThreadPool線程池的使用,線程池工具類用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
SpringBoot之?dāng)r截器與過(guò)濾器解讀
這篇文章主要介紹了SpringBoot之?dāng)r截器與過(guò)濾器解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07

