後端對前臺傳遞的日期型別處理的兩種方式
大家平時可能接觸到前臺傳到後臺的日期型別,那麼大家是如何處理的呢?我先說說我之前是怎麼處理的吧!
1、@JsonFormat註解
我之前一直使用這種方式來接收前臺傳進來的日期型別,當初感覺挺好用的,一直用一直爽,直到有一天,前端傳進來的日期型別變了,本來的格式是yyyy-MM-dd HH:mm:ss,突然有個資料成了yyyy-MM-dd, 就導致後臺報錯,型別轉換異常。
程式碼如下:
public class User { @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date birthday; }
錯誤資訊:
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'user' on field 'birthday': rejected value [2019-05-27]; codes [typeMismatch.user.birthday,typeMismatch.birthday,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.birthday,birthday]; arguments []; default message [birthday]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'birthday'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat java.util.Date] for value '2019-05-27'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2019-05-27]]
然後前端就會釘釘滴滴你,伺服器內部錯誤,然後你看了半天,沒問題啊,最後實在沒辦法,是不是你日期格式傳的有問題啊,把你傳的引數發過來,最後一看果真是這出了問題。這個時候你可能跟我一樣把接收的格式改一下,但是萬一前端他傳進來的日期格式又變了你該怎麼辦呢?
所以再給大家說第二種處理方式!
2、轉換器
這個也是我在經歷了跟前端各種鬥智鬥勇之後,學習到的一個方法,比起上面註解的方式,這種方式擴充套件性更強,而且可以同時處理多種資料格式。
我們先來看一下,如果定義這個轉換器
@Component public class DateConverter implements Converter<String, Date> { private static final String dateFormat = "yyyy-MM-dd HH:mm:ss"; private static final String shortDateFormat = "yyyy-MM-dd"; private static final String timeStampFormat = "^\\d+$"; private static final String hDateFormat = "yyyy年MM月dd日 HH:mm:ss"; private static final String hshortDateFormat = "yyyy年MM月dd日"; @Override public Date convert(String value) { if (StringUtils.isEmpty(value)) { return null; } value = value.trim(); try { if (value.contains("-")) { SimpleDateFormat formatter; if (value.contains(":")) { formatter = new SimpleDateFormat(dateFormat); } else { formatter = new SimpleDateFormat(shortDateFormat); } return formatter.parse(value); } else if (value.matches(timeStampFormat)) { Long lDate = new Long(value); return new Date(lDate); } else if (value.contains("年")) { SimpleDateFormat formatter; if (value.contains(":")) { formatter = new SimpleDateFormat(hDateFormat); } else { formatter = new SimpleDateFormat(hshortDateFormat); } return formatter.parse(value); } } catch (Exception e) { throw new RuntimeException(String.format("parser %s to Date fail", value)); } throw new RuntimeException(String.format("parser %s to Date fail", value)); } }
上面的年月日格式是我最近的專案中是這種格式,所以是我擴充套件新加的,所以通過轉化器的這種方式,請求進來進來之後,如果引數中有日期格式,那麼首先會進入轉換器中進行解析,通過上面的程式碼大家很容易看出,通過傳進來的格式判斷日期是哪種格式,然後再進行解析,最後返回一個Date型別,進入我們的業務程式碼處理業務。
但是如果你傳進來的日期格式不符合規範或者說沒有定義格式,那麼在轉換的過程中,還是會報錯。所以我們一般最好跟前端規定好某種格式,要麼同意yyyy-MM-dd的格式,要麼yyyy年MM月dd日,不要一個介面一個格式,這樣處理起來也是很費勁的。
3、經驗之談
上週寫一個介面,業務程式碼也不是很複雜,但是程式碼的量還是有點東西的,我是真的有點頂不住啊,所以花了一早上把這個介面重構了一下,最後主方法從70多行,減少到了10來行,看起來瞬間舒暢多了,雖然花了一早上,但是還是挺值得的,所以大家寫程式碼的過程中,能重構的程式碼最好還是重