亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

徹底解決Spring mvc中時間的轉(zhuǎn)換和序列化等問題

 更新時間:2019年09月19日 09:29:00   作者:碼農(nóng)小胖哥  
這篇文章主要介紹了徹底解決Spring mvc中時間的轉(zhuǎn)換和序列化等問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

痛點

在使用Spring mvc 進行開發(fā)時我們經(jīng)常遇到前端傳來的某種格式的時間字符串無法用java8的新特性java.time包下的具體類型參數(shù)來直接接收。 我們使用含有java.time封裝類型的參數(shù)接收也會報反序列化問題,在返回前端帶時間類型的同樣會出現(xiàn)一些格式化的問題。今天我們來徹底解決他們。

建議

其實最科學(xué)的建議統(tǒng)一使用時間戳來代表時間。這個是最完美的,避免了前端瀏覽器的兼容性問題,同時也避免了其它一些中間件的序列化/反序列化問題。但是用時間表達可能更清晰語義化。兩種方式各有千秋,如果我們堅持使用java8的時間類庫也不是沒有辦法。下面我們會以java.time.LocalDateTime為例逐一解決這些問題。

局部注解方式

網(wǎng)上有很多文章說該注解是前端指向后端的,也就是前端向后端傳遞時間參數(shù)格式化使用的,這沒有錯!但是有一個小問題,該方式只能適用于不涉及反序列化的情況下。也就是以下場景才適用:

 @GetMapping("/local")
 public Map<String, String> data(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime localDateTime) {
  Map<String, String> map = new HashMap<>(1);
  map.put("data", localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
  return map;
 }

如果你在下面這個場景使用就不行了:

@Data
public class UserInfo {

 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 private LocalDateTime birthday;
 private String name;
 private Integer age;
}


 @PostMapping("/user")
 public Object postData(@RequestBody UserInfo userInfo) {
  System.out.println("userInfo = " + userInfo);
  return userInfo;
 }

原因是Post請求參數(shù)在body中,需要反序列化成對象。默認是jackson類庫來進行反序列化,并不觸發(fā)@DateTimeFormat注解機制。這時我們就需要使用jackson的格式化注解@JsonFormat。我們將實體類UserInfo改造成下面的就可以了:

@Data
public class UserInfo {

 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
 private LocalDateTime birthday;
 private String name;
 private Integer age;
}

以上兩個注解可以并存,但是一定要清楚各自的使用場景。這里還有一個小細節(jié):格式一定要對應(yīng)好時間類型。比如yyyy-MM-dd 對應(yīng)java.time.LocalDate 。想再個性化一些@JsonFormat 可以被@JsonDeserialize和@JsonSerialize 代替。但是它們的using參數(shù)需要你自己實現(xiàn)為你對應(yīng)的時間類型類型。如果@JsonFormat、@JsonDeserialize和@JsonSerialize同時存在@JsonFormat的優(yōu)先級要更高。

局部處理的好處

局部處理的好處在于八個字:百花齊放,百家爭鳴 ??梢员3侄鄻有浴€性化 。但是局部帶來了一個新的問題 :沒有共同的標準 、不兼容。進而不方便維護。所以有時候基于業(yè)務(wù)需要我們?nèi)只梢越y(tǒng)一管理。下面我們將講解如何進行全局化配置。

全局化化時間格式配置

全局化其實也是基于 @DateTimeFormat 和@JsonFormat 兩種場景來進行配置。對于@DateTimeFormat的場景我們通過實現(xiàn)Spring提供的接口:

DateTimeFormatter :

  // 時間格式化
 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);

類型轉(zhuǎn)換接口:

org.springframework.core.convert.converter.Converter<S,T>

實現(xiàn):

 @Bean
 public Converter<String, LocalDateTime> localDateConverter() {
  return new Converter<String, LocalDateTime>() {
   @Override
   public LocalDateTime convert(String source) {
    return LocalDateTime.parse(source, FORMATTER);
   }
  };
 }

或者格式化接口:

org.springframework.format.Formatter<T>

實現(xiàn) :

@Bean
 public Formatter<LocalDateTime> localDateFormatter() {
  return new Formatter<LocalDateTime>() {
   @Override
   public LocalDateTime parse(String text, Locale locale) throws ParseException {
    return LocalDateTime.parse(text, FORMATTER);
   }

   @Override
   public String print(LocalDateTime object, Locale locale) {
    return object.format(FORMATTER);
   }
  };
 }

以上兩個接口的實現(xiàn)都要注冊為Spring Bean,配置的時候二者選其一即可,其中S即Source也就是來源,其實就是前端的時間字符串。T即Target也就是目標,代表你需要轉(zhuǎn)化或者格式化的時間java類型。那么對于時間序列化和反序列化我們進行如下配置就行了(基于默認jackson,以LocalDateTime 為例):

 @Bean
 public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

  return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
     // 反序列化
    .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(FORMATTER))
     // 序列化
    .serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(FORMATTER));
 }

同樣該jsonMapper自定義構(gòu)建器要注冊成Spring Bean才行。

全局配置要點

全局配置的一些優(yōu)缺點上面已經(jīng)闡述了,這里我還是要啰嗦一下要點避免你踩坑。全局配置跟局部配置一樣。同樣要約定pattern。這就要求我們?nèi)直3忠恢?。我們可以實現(xiàn)多個以上的全局配置來對其他諸如LocalDate、OffsetDateTime 的適配。同時如果我們接入了其它一些需要用到序列化/反序列化的中間件,比如redis、rabbitmq,我們也要注意進行適配。

總結(jié)

通過以上對時間格式的局部和全局處理方式的介紹,相信困擾你的Spring mvc 時間問題不會再存在了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

作者:碼農(nóng)小胖哥

來源:https://segmentfault.com/a/1190000020423352

相關(guān)文章

  • Effective Java 在工作中的應(yīng)用總結(jié)

    Effective Java 在工作中的應(yīng)用總結(jié)

    《Effective Java》是一本經(jīng)典的 Java 學(xué)習(xí)寶典,值得每位 Java 開發(fā)者閱讀。下面文章即是將書中和平日工作較密切的知識點做了部分總結(jié),需要的朋友可以參考下
    2021-09-09
  • 解析Spring?漏洞及其修復(fù)方案

    解析Spring?漏洞及其修復(fù)方案

    官宣了最近網(wǎng)傳的Spring漏洞。攻擊者利用該漏洞,可在未授權(quán)的情況下遠程執(zhí)行命令,今天通過本文給大家普及下漏洞分析影響范圍及解決方案,感興趣的朋友跟隨小編一起看看吧
    2022-04-04
  • Java并發(fā)LinkedBlockingQueue源碼分析

    Java并發(fā)LinkedBlockingQueue源碼分析

    這篇文章主要為大家介紹了Java并發(fā)LinkedBlockingQueue源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • IDEA斷點調(diào)試,斷點不起作用的解決

    IDEA斷點調(diào)試,斷點不起作用的解決

    這篇文章主要介紹了IDEA斷點調(diào)試,斷點不起作用的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring你不知道的一種解耦模式

    Spring你不知道的一種解耦模式

    本文介紹一種方法,服務(wù)定位模式Service?Locator?Pattern來解決,它幫助我們消除緊耦合實現(xiàn)及其依賴性,并提出將服務(wù)與其具體類解耦
    2023-01-01
  • Intellij IDEA 配置Subversion插件實現(xiàn)步驟詳解

    Intellij IDEA 配置Subversion插件實現(xiàn)步驟詳解

    這篇文章主要介紹了Intellij IDEA 配置Subversion插件實現(xiàn)步驟詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • IDEA 中 30 秒創(chuàng)建一個 Spring Cloud Alibaba 工程

    IDEA 中 30 秒創(chuàng)建一個 Spring Cloud Alibaba 工程

    這篇文章主要介紹了IDEA 中 30 秒生成 Spring Cloud Alibaba 工程,本文通過圖文并茂的形式給大家介紹的非常詳細對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • 詳解Java中的增強 for 循環(huán) foreach

    詳解Java中的增強 for 循環(huán) foreach

    foreach 是 Java 中的一種語法糖,幾乎每一種語言都有一些這樣的語法糖來方便程序員進行開發(fā),編譯期間以特定的字節(jié)碼或特定的方式來對這些語法進行處理。能夠提高性能,并減少代碼出錯的幾率。
    2017-05-05
  • mybatis如何實現(xiàn)saveOrUpdate

    mybatis如何實現(xiàn)saveOrUpdate

    這篇文章主要介紹了mybatis如何實現(xiàn)saveOrUpdate問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • SpringBoot+Quartz實現(xiàn)動態(tài)定時任務(wù)

    SpringBoot+Quartz實現(xiàn)動態(tài)定時任務(wù)

    這篇文章主要為大家詳細介紹了springBoot+Quartz實現(xiàn)動態(tài)定時任務(wù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評論