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;

 

一一哥Sun CSDN认证博客专家 Elasticsearch Java 架构
十年软件开发授课经验,专注大学生毕业设计及面试求职私塾式指导!对Android/JavaWeb/微服务/H5等技术领域有深入研究!曾任国内最大的智能物联网平台架构师,参与国内最大的智能物流系统平台天眼/冷链/订单/车次系统研发;曾主导国内首款国学教育App及后台架构;负责大庆油田采油管理系统,铝业云计算系统,湖南广电地面波机顶盒等项目的研发。目前担任某著名培训机构教学主管,培养了大批入职阿里,IBM,百度,国家电网等名企的高薪学生.本人坚持只有一心做教育,才能做一流教育的理念,被学生爱称为"一一哥"!QQ:2312119590,今日头条号:一一哥Sun;知乎ID:一一哥
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页