org.springframework.validation.BindException異常解決

org.springframework.validation.BindException異常解決

一. 異常現象

我在進行開發平臺後臺管理項目開發的時候,需要對token進行管理,其中需要對token進行編輯,效果如下:

結果在編輯token的時候,產生了如下現象:

token無法被編輯,阻塞了編輯操作的正常進行!

查看瀏覽器控制檯,發現出現了400狀態碼:

 並且開發工具控制檯出現如下異常信息:

[http-nio-8080-exec-22] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'userToken' on field 'expireTime': rejected value [1588986551000]; codes [typeMismatch.userToken.expireTime,typeMismatch.expireTime,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userToken.expireTime,expireTime]; arguments []; default message [expireTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'expireTime'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "1588986551000"]
Field error in object 'userToken' on field 'startTime': rejected value [1588468151000]; codes [typeMismatch.userToken.startTime,typeMismatch.startTime,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userToken.startTime,startTime]; arguments []; default message [startTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'startTime'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "1588468151000"]]

二. 異常原因

從上面的異常信息中,我提取出核心的異常信息如下:

 ...Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'expireTime'...nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "1588986551000"
 ​
 rejected value [1588986551000]; codes [typeMismatch.userToken.expireTime,typeMismatch.expireTime,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userToken.expireTime,expireTime]; arguments []; default message [expireTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'expireTime'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "1588986551000"]

從異常信息可以看出,是因爲前端頁面以字符串形式傳遞日期時間字符串到後臺接口,默認的SpringMVC處理器無法將java.lang.String類型的字符串轉換成java.util.Date類型,進而導致IllegalArgumentException: Could not parse date,歸根結底就是前端頁面中的日期時間字符串與後端JavaBean類中的Date類型不匹配,typeMismatch.userToken.expireTime,typeMismatch.java.util.Date,typeMismatch!

三. 解決辦法

解決辦法其實有多種,其實只要保證前後端參數可以實現轉換就行了,所以基於這種思路,我提供如下幾種解決辦法。

解決方法一:

在後端的日期類型的字段上,添加如下註解:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date expireTime;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;

因爲我的前端頁面,是普通的html頁面,且參數是以表單形勢傳遞的,如下:

 

所以利用@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")註解格式化前端傳遞進來的日期時間參數形式;

利用@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")格式化後端對外輸出的日期時間格式。

解決方法二:

第一種解決方法,需要在每個有日期時間類型字段的類中,都添加那樣的2個註解,當代碼較多時,就有些麻煩,可以編寫一個全局的轉換器,代碼如下:

package com.yyg.openapi.convert;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author 一一哥
 * @Blame yiyige
 * @Since Created in 2020/6/29
 */
public class CustomDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

}

 然後把該類在spring.xml文件中進行註冊配置。

<!--全局的日期時間轉換器,解決前後端時間類型不匹配而導致的400異常!-->
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.yyg.openapi.convert.CustomDateConverter"/>
            </list>
        </property>
    </bean>

此時JavaBean類中的屬性,只需要格式化對外輸出的類型,如下即可:

 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date expireTime;
     
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date startTime;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章