1. 程式人生 > >後端對前臺傳遞的日期型別處理的兩種方式

後端對前臺傳遞的日期型別處理的兩種方式

大家平時可能接觸到前臺傳到後臺的日期型別,那麼大家是如何處理的呢?我先說說我之前是怎麼處理的吧!

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來行,看起來瞬間舒暢多了,雖然花了一早上,但是還是挺值得的,所以大家寫程式碼的過程中,能重構的程式碼最好還是重