本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
在《详解SpringMVC中的Errors和BindingResult数据验证》这篇文章中,我们已经学习了一个案例,本文将继续学习一个数据绑定失败的案例。
下面先看看控制器DataBinderErrorTestController的实现代码:
package com.xttblog.chapter4.web.controller; //省略import public class DataBinderErrorTestController extends SimpleFormController { public DataBinderErrorTestController() { setCommandClass(DataBinderTestModel.class); setCommandName("dataBinderTest"); } @Override protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception { //如果表单提交有任何错误都会再回到表单展示页面 System.out.println(errors); return super.showForm(request, response, errors); } @Override protected void doSubmitAction(Object command) throws Exception { System.out.println(command); //表单提交成功(数据绑定成功)进行功能处理 } @Override protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { super.initBinder(request, binder); //注册自定义的属性编辑器 //1、日期 DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); CustomDateEditor dateEditor = new CustomDateEditor(df, true); //表示如果命令对象有Date类型的属性,将使用该属性编辑器进行类型转换 binder.registerCustomEditor(Date.class, dateEditor); //自定义的电话号码编辑器 binder.registerCustomEditor(PhoneNumberModel.class, new PhoneNumberEditor()); } }
此处我们使用SimpleFormController:
- showForm:展示表单,当提交表单有任何数据绑定错误会再回到该方法进行表单输入(在此处我们打印错误对象);
- doSubmitAction:表单提交成功,只要当表单的数据到命令对象绑定成功时,才会执行;
spring配置文件chapter4-servlet.xml
<bean name="/dataBindError" class="com.xttblog.web.controller.DataBinderErrorTestController"> <property name="formView" value="bindAndValidate/input"/> <property name="successView" value="bindAndValidate/success"/> </bean>
视图页面(WEB-INF/jsp/bindAndValidate/input.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!-- 表单的命令对象名为dataBinderTest --> <form:form commandName="dataBinderTest"> <form:errors path="*" cssStyle="color:red"></form:errors><br/><br/> bool:<form:input path="bool"/><br/> phoneNumber:<form:input path="phoneNumber"/><br/> date:<form:input path="date"/><br/> <input type="submit" value="提交"/> </form:form>
此处一定要使用form标签库,借此我们可以看到它的强大支持(别的大部分Web框架所不具备的,展示用户验证失败的数据)。
- <form:form commandName="dataBinderTest">:指定命令对象为dataBinderTest,默认command;
- <form:errors path="*" cssStyle="color:red"></form:errors>:显示错误消息,当提交表单有错误时展示错误消息(数据绑定错误/数据不合法);
- <form:input path="bool"/>:等价于(<input type=’text’>),但会从命令对象中取出bool属性进行填充value属性,或如果表单提交有错误会从错误对象取出之前的错误数据(而非空或默认值);
- <input type="submit" value="提交"/>:spring没有提供相应的提交按钮,因此需要使用html的。
在地址栏输入如下地址:http://localhost:9080/springmvc-chapter4/dataBindError
全部是错误数据,即不能绑定到我们的命令对象;当提交表单后,我们又回到表单输入页面,而且输出了一堆错误信息。
- 错误消息不可读;
- 表单元素可以显示之前的错误的数据,而不是默认值/空;
这里最大的问题是不可读的错误消息,如何让这些错误消息可读呢?
首先我们看我们的showForm方法里输出的“errors”错误对象信息:
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors Field error in object 'dataBinderTest' on field 'bool': rejected value [www]; codes [typeMismatch.dataBinderTest.bool,typeMismatch.bool,typeMismatch.boolean,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.bool,bool]; arguments []; default message [bool]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'bool'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [www]] Field error in object 'dataBinderTest' on field 'date': rejected value [123]; codes [typeMismatch.dataBinderTest.date,typeMismatch.date,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'date'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "123"] Field error in object 'dataBinderTest' on field 'phoneNumber': rejected value [123]; codes [typeMismatch.dataBinderTest.phoneNumber,typeMismatch.phoneNumber,typeMismatch.cn.javass.chapter4.model.PhoneNumberModel,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.phoneNumber,phoneNumber]; arguments []; default message [phoneNumber]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'cn.javass.chapter4.model.PhoneNumberModel' for property 'phoneNumber'; nested exception is java.lang.IllegalArgumentException: 类型转换失败,需要格式[010-12345678],但格式是[123]]
数据绑定失败(类型不匹配)会自动生成如下错误码(错误码对应的错误消息按照如下顺序依次查找):
- typeMismatch.命令对象名.属性名
- typeMismatch.属性名
- typeMismatch.属性全限定类名(包名.类名)
- typeMismatch
内部使用MessageCodesResolver解析数据绑定错误到错误码,默认DefaultMessageCodesResolver,因此想要详细了解如何解析请看其javadoc;建议使用第1个进行错误码的配置。
因此修改我们的messages.properties添加如下错误消息(需要执行NativeToAscii):
typeMismatch.dataBinderTest.date=您输入的数据格式错误,请重新输入(格式:2012-03-19 22:17:17) #typeMismatch.date=2 #typeMismatch.java.util.Date=3 #typeMismatch=4
再次提交表单我们会看到我们设置的错误消息。到此,数据绑定错误我们介绍完了,接下来我们再看一下数据不合法错误。
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » 详解SpringMVC中的数据验证示例