Springboot全局日期格式化

說在前邊

最近部門幾位同事受了一些委屈相繼離職,共事三年臨別之際頗有不舍,待一切手續(xù)辦妥帖,寒暄過后送他們出公司,幾個老哥臨別時沖我鬼魅一笑,我頓時心里一緊有種不好的預(yù)感,這事絕對沒有這么簡單。等我接手這幾個大佬的項目后,應(yīng)驗了我的預(yù)感,此刻我居然有點后悔,為啥送別之時沒揍他們一頓!哈哈哈~ 而這種打人的沖動,在我開始優(yōu)化幾位老哥的項目時候,變得越來越強烈。

有個坑

技術(shù)部每個月都會組織一下代碼走查及優(yōu)化,以前是各自審查優(yōu)化自己的項目,如今幾位老哥的離職他們的項目就落到了我的頭上。對于程序員來說最痛苦的事情就是接手別人的項目,還要做優(yōu)化改造,因為這一點也不比重構(gòu)一遍項目簡單。不過,軍令在前,沒辦法硬著頭皮上吧!

第一個優(yōu)化的點就讓我有點崩潰,這幾個大佬的技能能力很強,一直都是我學(xué)習(xí)的榜樣,但在項目里幾乎所有的日期格式化都這樣用?SimpleDateFormat?,像如下代碼這樣實現(xiàn),emm~ ,受過傷的男人怎么啥事都做的出來,哈哈哈~

SvcOrderDailyStatisticsPo orderDailyStatisticsPo =newSvcOrderDailyStatisticsPo();SimpleDateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd");DatestationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));orderDailyStatisticsPo.setStatisticalDate(stationTime);

而且項目中的時間和日期API用的也比較混亂,考慮到?java.util.Date?和?java.util.Calendar?不支持時區(qū),且非線程安全,對于日期的計算相對繁瑣,技術(shù)部一致要求用JDK1.8以后的?java.time?LocalDateTime?。但不少人還是在用?java.util.Date?和?java.util.Calendar?處理日期。

優(yōu)化方案

時間格式化是使用頻率非常高的,如何讓時間格式化變得既簡單又不用重復(fù)造輪子,那么就應(yīng)將它抽象出來,作為全局的日期格式化處理,下面就結(jié)合實踐簡單介紹下幾種優(yōu)化方案。

測試地址:?http://127.0.0.1:8080/timeTest

@GetMapping("/timeTest")publicOrderInfotimeTest(){? ? ? ? OrderInfo order =newOrderInfo();? ? ? ? order.setCreateTime(LocalDateTime.now());? ? ? ? order.setUpdateTime(newDate());returnorder;? ? }

1、@JsonFormat注解

使用?@JsonFormat?注解格式化時間,應(yīng)該算是一個基本操作了,大部分開發(fā)者都應(yīng)用此種方式,簡單方便。

/** *@Author: xiaofu *@Description: */publicclassOrderInfo{@JsonFormat(locale ="zh", timezone ="GMT+8", pattern ="yyyy-MM-dd HH:mm:ss")privateLocalDateTime createTime;@JsonFormat(locale ="zh", timezone ="GMT+8", pattern ="yyyy-MM-dd HH:mm:ss")privateDate updateTime;publicLocalDateTime getCreateTime() {returncreateTime;? ? }publicvoid setCreateTime(LocalDateTime createTime) {this.createTime = createTime;? ? }publicDate getUpdateTime() {returnupdateTime;? ? }publicvoid setUpdateTime(Date updateTime) {this.updateTime = updateTime;? ? }}

測試一下結(jié)果,發(fā)現(xiàn)?Date?類型和?LocalDateTime?類型都格式化成功,但還是有個問題,這樣做仍然比較繁瑣,每個實體類的日期字段都要加?@JsonFormat?注解,重復(fù)的工作量也不小。接著往下看~

2、全局配置 (1)

Springboot?已經(jīng)為我們提供了日期格式化?${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}?,這里我們需要進行全局配置,配置比較簡單,也無需在實體類屬性上添加?@JsonFormat?注解。

/** *@Author: xiaofu *@Description: */publicclassOrderInfo{//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")privateLocalDateTime createTime;//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")privateDate updateTime;publicLocalDateTimegetCreateTime(){returncreateTime;? ? }publicvoidsetCreateTime(LocalDateTime createTime){this.createTime = createTime;? ? }publicDategetUpdateTime(){returnupdateTime;? ? }publicvoidsetUpdateTime(Date updateTime){this.updateTime = updateTime;? ? }}

只需要用?@Configuration?定義一個配置類,注入兩個?Bean?即可完成全局日期格式化處理,這種方式也是當前我項目中正在用的方式。

/** *@Author: xiaofu *@Description: */@ConfigurationpublicclassLocalDateTimeSerializerConfig{@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")privateString pattern;@BeanpublicLocalDateTimeSerializer localDateTimeDeserializer() {returnnew LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));? ? }@BeanpublicJackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {returnbuilder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());? ? }}

這種方式可支持?Date?類型和?LocalDateTime?類型并存,那么有一個問題就是現(xiàn)在全局時間格式是?yyyy-MM-dd HH:mm:ss?,但有的字段卻需要?yyyy-MM-dd?格式咋整?

那就需要配合?@JsonFormat?注解使用,在特定的字段屬性添加?@JsonFormat?注解即可,因為?@JsonFormat?注解優(yōu)先級比較高,會以?@JsonFormat?注解標注的時間格式為主。

3、全局配置 (2)

這種全局配置的實現(xiàn)方式與上邊的效果是一樣的,不過,要注意的是使用這種配置后,字段手動配置?@JsonFormat?注解將不再生效。

/** *@Author: xiaofu *@Description: */publicclassOrderInfo{//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")privateLocalDateTime createTime;//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")privateDate updateTime;publicLocalDateTimegetCreateTime(){returncreateTime;? ? }publicvoidsetCreateTime(LocalDateTime createTime){this.createTime = createTime;? ? }publicDategetUpdateTime(){returnupdateTime;? ? }publicvoidsetUpdateTime(Date updateTime){this.updateTime = updateTime;? ? }}

/**

* @Author: xiaofu

* @Description:

*/@ConfigurationpublicclassLocalDateTimeSerializerConfig{@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")privateStringpattern;@Bean@PrimarypublicObjectMapperserializingObjectMapper() {ObjectMapperobjectMapper =newObjectMapper();JavaTimeModulejavaTimeModule =newJavaTimeModule();? ? ? ? javaTimeModule.addSerializer(LocalDateTime.class,newLocalDateTimeSerializer());? ? ? ? javaTimeModule.addDeserializer(LocalDateTime.class,newLocalDateTimeDeserializer());? ? ? ? objectMapper.registerModule(javaTimeModule);returnobjectMapper;? ? }? ? publicclassLocalDateTimeSerializerextendsJsonSerializer<LocalDateTime>{@Overridepublic void serialize(LocalDateTimevalue,JsonGeneratorgen,SerializerProviderserializers)throwsIOException{? ? ? ? ? ? gen.writeString(value.format(ofPattern(pattern)));? ? ? ? }? ? }? ? publicclassLocalDateTimeDeserializerextendsJsonDeserializer<LocalDateTime>{@OverridepublicLocalDateTimedeserialize(JsonParserp,DeserializationContextdeserializationContext)throwsIOException{returnLocalDateTime.parse(p.getValueAsString(), ofPattern(pattern));? ? ? ? }? ? }}

總結(jié)

分享了一個?Springboot?項目開發(fā)過程中的一個小技巧,也順便吐槽一下項目優(yōu)化中遇到的坑,優(yōu)化別的人的代碼雖然是一件比較痛苦的事情,但在這個過程中確實能學(xué)習(xí)到很多技巧,對個人的技能提升也是很有幫助,因為都是些能夠?qū)崒嵲谠谔岣唛_發(fā)效率的干貨。



原文?https://segmentfault.com/a/1190000022355979

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容