1. 程式人生 > 程式設計 >Springboot 全域性日期格式化處理的實現

Springboot 全域性日期格式化處理的實現

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

Springboot 全域性日期格式化處理的實現

有個坑

技術部每個月都會組織一下程式碼走查及優化,以前是各自審查優化自己的專案,如今幾位老哥的離職他們的專案就落到了我的頭上。對於程式設計師來說最痛苦的事情就是接手別人的專案,還要做優化改造,因為這一點也不比重構一遍專案簡單。不過,軍令在前,沒辦法硬著頭皮上吧!

第一個優化的點就讓我有點崩潰,這幾個大佬的技能能力很強,一直都是我學習的榜樣,但在專案裡幾乎所有的日期格式化都這樣用 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",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註解,重複的工作量也不小。接著往下看~

Springboot 全域性日期格式化處理的實現

2、全域性配置 (1)

Springboot 已經為我們提供了日期格式化 ${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss},這裡我們需要進行全域性配置,配置比較簡單,也無需在實體類屬性上新增@JsonFormat註解。

/**
 * @Author: xiaofu
 * @Description:
 */
public class OrderInfo {

  //@JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss")
  private LocalDateTime createTime;

  //@JsonFormat(locale = "zh",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",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 全域性日期格式化處理的實現的文章就介紹到這了,更多相關Springboot 全域性日期格式化內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!