详解SpringMVC中的Errors和BindingResult数据验证

JAVA herman 1769浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

表单数据验证可以有效的过滤掉一些垃圾数据和一部分机器注册。Struts2中有完整的验证接口,SpringMVC中也同样的为我们提供了对应的验证机制。本文将详细的介绍SpringMVC中的数据验证Errors和BindingResult。

数据验证

  • 数据绑定失败:比如需要数字却输入了字母;
  • 数据不合法:可以认为是业务错误,通过自定义验证器验证,如用户名长度必须在5-20之间,我们却输入了100个字符等;
  • 错误对象:当我们数据绑定失败或验证失败后,错误信息存放的对象,我们叫错误对象,在Spring Web MVC中Errors是具体的代表者;线程不安全对象;
  • 错误消息:是硬编码,还是可配置?实际工作应该使用配置方式,我们只是把错误码(errorCode)放入错误对象,在展示时读取相应的错误消息配置文件来获取要显示的错误消息(errorMessage);

验证流程

SpringMVC中的数据验证流程

  • 首先进行数据绑定验证,如果验证失败会通过MessageCodesResolver生成错误码放入Errors错误对象;
  • 数据不合法验证,通过自定义的验证器验证,如果失败需要手动将错误码放入Errors错误对象;

错误对象和错误消息

错误对象的代表者是Errors接口,并且提供了几个实现者,在Spring Web MVC中我们使用的是如下实现:

Errors接口

  • getFieldValue:可以得到验证失败的失败值,这是其他Web层框架很少支持的,这样就可以给用户展示出错时的值(而不是空或其他的默认值等)。
  • BindingResult:代表数据绑定的结果,继承了Errors接口。
  • BindException:代表数据绑定的异常,它继承Exception,并实现了BindingResult,这是内部使用的错误对象。
  • Errors:存储和暴露关于数据绑定错误和验证错误相关信息的接口,提供了相关存储和获取错误消息的方法:
package org.springframework.validation;  
public interface Errors {  
	//全局错误消息(验证/绑定对象全局的)
	//注册一个全局的错误码()  
	void reject(String errorCode);  
	//注册一个全局的错误码,当根据errorCode没有找到相应错误消息时,使用defaultMessage作为错误消息  
	void reject(String errorCode, String defaultMessage);  
	//注册一个全局的错误码,当根据errorCode没有找到相应错误消息时(带错误参数的),使用defaultMessage作为错误消息  
	void reject(String errorCode, Object[] errorArgs, String defaultMessage);  
	//全局错误消息(验证/绑定整个对象的)
	//局部错误消息(验证/绑定对象字段的)
	//注册一个对象字段的错误码,field指定验证失败的字段名  
	void rejectValue(String field, String errorCode);  
	void rejectValue(String field, String errorCode, String defaultMessage);  
	void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage);  
	//局部错误消息(验证/绑定对象字段的)
	boolean hasErrors();      ////是否有错误  
	boolean hasGlobalErrors(); //是否有全局错误  
	boolean hasFieldErrors();  //是否有字段错误  
	Object getFieldValue(String field); //返回当前验证通过的值,或验证失败时失败的值;  
}  

控制器

package com.xttblog.chapter4.web.controller;  
//省略import  
public class ErrorController extends AbstractCommandController {  
	public ErrorController() {  
		  setCommandClass(DataBinderTestModel.class);  
		  setCommandName("command");  
	}  
	@Override  
	protected ModelAndView handle(HttpServletRequest req, 
		HttpServletResponse resp, Object command, 
		BindException errors) throws Exception {     
		  //表示用户名不为空  
		  errors.reject("username.not.empty");  
		  //带有默认错误消息  
		  errors.reject("username.not.empty1", "用户名不能为空1");  
		  //带有参数和默认错误消息          
		  errors.reject("username.length.error", new Object[]{5, 10});  
		  //得到错误相关的模型数据  
		  Map model = errors.getModel();  
		  return new ModelAndView("bindAndValidate/error", model);  
	}  
}  
  • errors.reject("username.not.empty"):注册全局错误码“username.not.empty”,我们必须提供messageSource来提供错误码“username.not.empty”对应的错误信息(如果没有会抛出NoSuchMessageException异常);
  • errors.reject("username.not.empty1", "用户名不能为空1"):注册全局错误码“username.not.empty1”,如果从messageSource没没有找到错误码“username.not.empty1”对应的错误信息,则将显示默认消息“用户名不能为空1”;
  • errors.reject("username.length.error", new Object[]{5, 10}):错误码为“username.length.error”,而且错误信息需要两个参数,如我们在我们的配置文件中定义“用户名长度不合法,长度必须在{0}到{1}之间”,则实际的错误消息为“用户名长度不合法,长度必须在5到10之间”
  • errors.getModel():当有错误信息时,一定将errors.getModel()放入我们要返回的ModelAndView中,以便使用里边的错误对象来显示错误信息。

spring配置文件chapter4-servlet.xml

<bean id="messageSource"  
       class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
    <property name="basename" value="classpath:messages"/>  
    <property name="fileEncodings" value="utf-8"/>  
    <property name="cacheSeconds" value="120"/>  
</bean>  
<bean name="/error" class="com.xttblog.chapter4.web.controller.ErrorController"/>

messageSource:用于获取错误码对应的错误消息的,而且bean名字默认必须是messageSource。

messages.properties(需要执行NativeToAscii)

username.not.empty=用户名不能为空  
username.length.error=用户名长度不合法,长度必须在{0}到{1}之间  

视图页面(WEB-INF/jsp/bindAndValidate/error.jsp)

<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>  
<!-- 表单的默认命令对象名为command -->  
<form:form commandName="command">  
    <form:errors path="*"></form:errors>  
</form:form>  
  • form标签库:此处我们使用了spring的form标签库;
  • <form:form commandName="command">:表示我们的表单标签,commandName表示绑定的命令对象名字,默认为command;
  • <form:errors path="*"></form:errors>:表示显示错误信息的标签,如果path为“*”表示显示所有错误信息。

接下来我们来看一下 数据绑定失败和数据不合法时,如何处理。

数据绑定失败

如我们的DataBinderTestModel类:

  • bool:boolean类型,此时如果我们前台传入非兼容的数据,则会数据绑定失败;
  • date:Date类型,此时如果我们前台传入非兼容的数据,同样会数据绑定失败;
  • phoneNumber:自定义的PhoneNumberModel类型,如果如果我们前台传入非兼容的数据,同样会数据绑定失败。

关于数据绑定失败的示例,我们下章见。本文示例源码下载链接:http://pan.baidu.com/s/1bpvohZp 密码:wgde

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 详解SpringMVC中的Errors和BindingResult数据验证