1. 程式人生 > >真沒想到,Springboot能這樣做全域性日期格式化,有點香!

真沒想到,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.Datejava.util.Calendar 不支援時區,且非執行緒安全,對於日期的計算相對繁瑣,技術部一致要求用JDK1.8以後的 java.time LocalDateTime。但不少人還是在用 java.util.Datejava.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專案開發過程中的一個小技巧,也順便吐槽一下專案優化中遇到的坑,優化別的人的程式碼雖然是一件比較痛苦的事情,但在這個過程中確實能學習到很多技巧,對個人的技能提升也是很有幫助,因為都是些能夠實實在在提高開發效率的乾貨。


小福利:

獲取到一些極客付費課程 ,噓~,免費 送給小夥伴們。關注公眾號回覆【極客】自行領取

相關推薦

想到Springboot這樣全域性日期格式化有點

最近面了一些公司,有一些 Java方面的架構、面試資料,有需要的小夥伴可以在公眾號【程式設計師內點事】裡,無套路自行領取 說在前邊 最近部門幾位同事受了一些委屈相繼離職,共事三年臨別之際頗有不捨,待一切手續辦妥帖,寒暄過後送他們出公司,幾個老哥臨別時衝我鬼魅一笑,我頓時心裡一緊有種不好的預感,這事絕對沒

一個有意思的小故事希望以後也有這種修養這樣厚道

而後 離開 十大 正在 一個 說道 給他 為什麽 我們 清朝的時候,常州有一個魏廉訪,他的父親是個醫生,樂善好施。 有一次魏老先生被請往一病人家中治病。 他離開後,病人發現藏在枕頭下的十兩銀子不見了。 病人的的兒子,懷疑是魏老先生拿了,就到老先生家,對他說:&ldqu

Java多執行緒可以分組這樣

前面的文章,棧長和大家分享過多執行緒建立的3種方式《實現 Java 多執行緒的 3 種方式》。 但如果執行緒很多的情況下,你知道如何對它們進行分組嗎? 和 Dubbo 的服務分組一樣,Java 可以對相同性質的執行緒進行分組。 來看下執行緒類 Thread 的所有構造方法。 如圖所示,帶有 Thr

PHP明細之間的關聯和having進行分組不推薦這樣只是為偷懶的辦法

1 -- 只求和wrt的資料,其它資料保持不變!SELECT A.return_id,A.relevant_id,A.order_id,A.deliver_order_id,A.product_id,A.returnNum,A.deliverNum,A.rdbData,SUM(wrt.quantity

微信和Python之間這樣玩的嘛漲見識了

安裝 pip3 install itchat Python學習資料或者需要程式碼、視訊加Python學習群:960410445 主要用到的方法: itchat.login() 微信掃描二維碼登入 itchat.get_friends() 返回完整的好友列表,每個好友為一個字典,

基本的輸出方法PHP可以這樣

在 PHP 中,有三種基本的輸出方法:echo , print 和 var_dump PHP echo , print 和 var_dump 語句 echo , print 和 var_dump 之間的差異: echo - 能夠輸出一個以上的字串 print -

【cuseronline的專欄】我一個人若肯花三至五年的時間專注的去一件事情總會有一些成績的吧。

技術方向1: Eclipse平臺技術愛好者,實踐者,5年以上Eclipse外掛、RCP開發經驗,對Eclipse外掛、RCP有深入的瞭解。熟悉Eclipse外掛,RCP,GEF,JDT,AST及IDE開發,瞭解EMF,OSGI,對程式碼自動化生成及MDA等也有一定的經驗和實踐。閱讀和研

在 Facebook我是這樣運維的

作者簡介 譚芝蘭 Facebook TechLead 在矽谷從事運維工作10多年。2012年至2016年先後在Twitter大資料平臺(Data Platform) SRE和工程效率組(Engineer Effectiveness)任職。2016年起就職於Facebook廣告部門,負責大資料和計

跳槽遇到背景調查你可以這樣

    背景調查是很多企業錄用員工前啟動的重要考查環節,如果在這個環節上被前領導“陷害“了,該如何挽救呢?前程無憂論壇網友給你支招…… [求助]前程無憂網友“kame3p”的困惑:     經過了一系列的面試,我終於接到了某500強公司的預錄用電話,要求我提供前直接領

我都xxx歲了繼續開發嗎?

# 前言 > 今天純文字,閱讀時間10分鐘左右 最近在看一本書《大型網站技術架構:核心原理與案例分析》,可以說是非常枯燥的一本書,在開頭幾章講解了網站的發展,介紹了一些架構中的常用名詞。雖然有點枯燥,但這本書很適合想從開發轉架構的同學。 其中講到了各個大型網站的發展歷史,無外乎是從一個很小的站點做起,隨著

Android使用Fragment得到Fragment內部控件findViewById()結果是Null--已經解決

文本 match ces ear creat 能夠 -s 兼容 mat 程序很easy。好長時間沒有搞定。郁悶。。。。。。。。。。。。在論壇咨詢,最終找到答案。 描寫敘述: 一個Activity:MainActivity。內部是一個Fragment:FragmentA。

寫一個dup2功能同樣的函數調用 fcntl 函數而且要有出錯處理

make argc exit post pre con version returns imp 實現的時候用到系統原來的dup函數 // mydup2.c // 2015/08/17 Lucifer Zhang version1.0 // write

qq46843大騙子qq我給他了一個網站然後他不掏錢大騙子真實記錄

讀取 道理 ava cep 總結 同步代碼塊 編程 類型 線程 qq46843大騙子qq他叫花總,大騙子!我給他做了一個網站,然後他不掏錢,大騙子真實記錄!qq46843大騙子qq,我給他做了一個網站,然後他不掏錢,大騙子真實記錄!有聊天截圖,真的不要相信,空間都是一些吹牛

西南seo大神帶你走在時代前沿把我機遇迎接挑戰

是我 要去 產品 特產 為什麽 挑戰 前沿 機會 互聯網+時代 走在時代前沿,帶領家庭生態農業農莊發展是否懷戀兒時那石磨磨出的面粉,是否對農村的自然風光,清新的空氣,叮咚的泉水意猶未盡,是否想念你孩童時的燒洋芋,或是在山上生上柴火掰幾個玉米烤熟時的味道,是否很想再追憶一下年

飛哥就是安全建設的內網安全有你不知道的事兒

內網安全who am i 各位博友見置頂博客第一章。信息安全從業7年,帽子沒有白過,也沒有在烏雲等src留過名,但是各位hacker的動機和大事我也關註過,一直從事於企業安全防護工作,識別內網資產的脆弱性,讓hacker小哥哥們不是那麽特別輕易拿下數據和網絡及站點。熱愛生活,熱愛自由。一路走來,沒有敵人,都是

電子秤廚房秤臺燈手表數字電子表、小家電移動電源MP3觸摸4按鍵感應/四通道觸控IC

3.1 n-1 資料 真誠 0ms 員工 工作 介紹 按鍵 我們的優勢:1:我司為VINTE/臺灣元泰半導體股份有限公司/VINKA的獨家授權大中華區代理商,產品渠道正宗,確保原裝正品,大量庫存現貨,客戶批量不懼假貨!2:公司工程力量雄厚,真誠技術服務支持,搭配原廠服務各種

SpringBoot返回date日期格式化解決返回為TIMESTAMP時間戳格式或8小時時間差(轉載)

@JSONField(format = "yyyy-MM-dd HH:mm:ss")  //FastJson包使用註解     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") //Jack

看準商機大學畢業生創業手機無線增值年盈利70多萬元

楊昕霖和張雪林都是蘭州理工大學畢業生,楊昕霖是2003屆計算機專業畢業生,張雪林是2004屆自動化專業的畢業生。 由於共同的興趣愛好,兩個在校大學生初次合作開始於2002年,當時他們一起製作的蘭州理工大學畢業生就業資訊網站,在甘肅省第四屆“挑戰杯”大學生課外科技製作大賽上獲得了二等獎。 20

Leetcode 213. House Robber II -打家劫舍每家都有一定數量的錢多家組成一個圓形首尾相鄰偷盜相鄰的兩家求可偷盜的最大金額

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are&

LeetCode 198. House Robber-打家劫舍每家都有一定數量的錢偷盜相鄰的兩家求可偷盜的最大金額

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping