< spring:bind path ="command.name" > name: < input type ="text" name ="name" value ="<c:out value=" ${status.value}" /> "/>(必须输入) < c:if test ="${status.error}" > < font color ="#FF0000" > 错误: < c:forEach items ="${status.errorMessages}" var ="error" > < c:out value ="${error}" /> </ c:forEach > </ font > </ c:if > </ spring:bind >
< spring:bind path ="command.name" > name: < input type ="text" name ="name" value ="<c:out value=" ${status.value}" /> "/>(必须输入) < c:if test ="${status.error}" > < font color ="#FF0000" > 错误: < c:forEach items ="${status.errorMessages}" var ="error" > < c:out value ="${error}" /> </ c:forEach > </ font > </ c:if > </ spring:bind >
Spring MVC为我们提供了类似struts validator的验证框架,但spring并非编写xml验证文件,而且是实现期自身提供的Validator接口,为我们的POJO javabean提供针对具体类的验证,非常方便,下面,我们就一起来实现这个功能
首先,我们先编写一个注册页面,只有两个字段,姓名和性别,这里要求姓名和性别都必须输入,而且性别只能输入0或1
register.jsp
<% @ page language = " java " import = " java.util.* " pageEncoding = " GB18030 " %> <% @ taglib prefix = " spring " uri = " http://www.springframework.org/tags " %> <% @ taglib uri = " http://java.sun.com/jsp/jstl/core " prefix = " c " %> <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > </ head > < body > < spring:bind path ="command.*" > < font color ="#FF0000" > < c:forEach items ="${status.errorMessages}" var ="error" > 错误: < c:out value ="${error}" />< br > </ c:forEach > </ font > </ spring:bind > < form action ="<%=request.getContextPath() %>/register.mvc" method ="post" > < spring:bind path ="command.name" > name: < input type ="text" name ="name" value ="<c:out value=" ${status.value}" /> "/>(必须输入) < c:if test ="${status.error}" > < font color ="#FF0000" > 错误: < c:forEach items ="${status.errorMessages}" var ="error" > < c:out value ="${error}" /> </ c:forEach > </ font > </ c:if > </ spring:bind ></ br > < spring:bind path ="command.sex" > sex: < input type ="text" name ="sex" /> (必须输入,且为0或1) < c:if test ="${status.error}" > < font color ="#FF0000" > 错误: < c:forEach items ="${status.errorMessages}" var ="error" > < c:out value ="${error}" /> </ c:forEach > </ font > </ c:if > </ spring:bind ></ br > < input type ="submit" value ="submit" /> </ form > </ body > </ html >
其中关于Spring bind标签和jstl标签可以先暂时忽略,后面酱油详细介绍
然后编写我们的表单对应POJO JavaBean
Student.java
package model; public class Student { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this .name = name; } public String getSex() { return sex; } public void setSex(String sex) { this .sex = sex; } }
编写我们的控制器controller RegisterStudentController.java
这个控制室是在我们通过验证后,将表单输入的内容显示在一个成功页面中,页面逻辑名用getSuccessView()获得,从spring配置文件中注入
package Action; import model.Student; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.SimpleFormController; public class RegisterStudentController extends SimpleFormController { public RegisterStudentController() { this .setCommandClass(Student. class ); } protected ModelAndView onSubmit(Object object, BindException arg1) throws Exception { Student stu = (Student)object; return new ModelAndView(getSuccessView(), " student " ,stu); } }
线面编写我们的
验证根据errors对象返回错误,我们有两种定制errors的方法
(1) errors.rejectValue("name","notnull",null, "用户名长度必须输入!"); rejectVlaue方法有4个参数: 1. Error Code 显示错误时,将根据错误代码识别错误信息类型。 2. Message Key上面关于ApplicationContext 的国际化支持时, 我们曾经谈及MessageSource的使用, 这里我们可以通过引入MessageSource实现提示信息的参数化,此时,本参数将用作.properties文件 中的消息索引。 3. Error Argument 如果提示信息中需要包含动态信息,则可通过此参数传递需要的动态信息对象。具 体参见ApplicationContext中关于国际化实现的描述。 4. Default Message 如果在当前MessageSource中没有发现Message Key对应的信息数据,则以此默认值返回。 这里我们暂时尚未考虑国际化支持,所有的信息都将通过Default Message返回
(2) ValidationUtils.rejectIfEmpty(errors, "name", "name", "姓名必须输入");
package model; import org.apache.oro.text.perl.Perl5Util; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; public class StudentValidator implements Validator { private static String SEX_REGEXP = " /^[0-1]$/ " ; public boolean supports(Class cls) { return cls.equals(Student. class ); } public void validate(Object object, Errors errors) { Student student = (Student)object; // if(student.getName().equals("")||student.getName()==null){ // errors.rejectValue("name", // "notnull", // null, // "用户名长度必须输入!"); // } ValidationUtils.rejectIfEmpty(errors, " name " , " name " , " 姓名必须输入 " ); ValidationUtils.rejectIfEmpty(errors, " sex " , " sex " , " 性别必须输入 " ); Perl5Util perl5Util = new Perl5Util(); if ( ! perl5Util.match(SEX_REGEXP, student.getSex())) { errors.rejectValue( " sex " , " not confirmat " , null , " 性别格式错误 " ); } } }
其中一下部分是用ORO正则表达式验证类库进行sex字段的正则验证
if ( ! perl5Util.match(SEX_REGEXP, student.getSex())) { errors.rejectValue( " sex " , " not confirmat " , null , " 性别格式错误 " ); }
配置文件:
web.xml
<? xml version="1.0" encoding="UTF-8" ?> < web-app version ="2.4" xmlns ="http://java.sun.com/xml/ns/j2ee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > < context-param > < param-name > contextConfigLocation </ param-name > < param-value > /WEB-INF/train-servlet.xml </ param-value > </ context-param > < servlet > < servlet-name > train </ servlet-name > < servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class > < load-on-startup > 0 </ load-on-startup > </ servlet > < servlet-mapping > < servlet-name > train </ servlet-name > < url-pattern > *.mvc </ url-pattern > </ servlet-mapping > < listener > < listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class > </ listener > < filter > < filter-name > character </ filter-name > < filter-class > Action.CharacterFilter </ filter-class > </ filter > < filter-mapping > < filter-name > character </ filter-name > < url-pattern > /* </ url-pattern > </ filter-mapping > < welcome-file-list > < welcome-file > index.jsp </ welcome-file > </ welcome-file-list > </ web-app >
train-servlet.xml
我们用 <property name="validator"> <bean class="model.StudentValidator"></bean> </property> 来定义验证类
用 <property name="commandClass"> <value>model.Student</value> </property> 来定义验证框架需要验证的类(这个属性对我们在页面上显示错误信息有用)
< bean id ="RegisterStudentController" class ="Action.RegisterStudentController" > < property name ="commandClass" > < value > model.Student </ value > </ property > < property name ="formView" > < value > register </ value > </ property > < property name ="successView" > < value > success </ value > </ property > < property name ="validator" > < bean class ="model.StudentValidator" ></ bean > </ property > </ bean > < bean id ="simpleUrlMapping" class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" > < property name ="mappings" > < props > < prop key ="/register.mvc" > RegisterStudentController </ prop > </ props > </ property > </ bean >
线面说明一下registe.jsp的两端代码
(1)
用spring:bind标签绑定Student类(由于在配置文件中配置了commandClass),我们在这里可以使用command.*代替Student.*,使用jstl迭代显示出errors对象中的所有错误信息
< spring:bind path ="command.*" > < font color ="#FF0000" > < c:forEach items ="${status.errorMessages}" var ="error" > 错误: < c:out value ="${error}" />< br > </ c:forEach > </ font > </spring:bind>
(2)
使用spring帮顶student的name属性,如果其error对象不为空,则单独显示这个属性的error信息
< spring:bind path ="command.name" > name: < input type ="text" name ="name" value ="<c:out value=" ${status.value}" /> "/>(必须输入) < c:if test ="${status.error}" > < font color ="#FF0000" > 错误: < c:forEach items ="${status.errorMessages}" var ="error" > < c:out value ="${error}" /> </ c:forEach > </ font > </ c:if > </ spring:bind >
最后一个是个注册成功页面 success.jsp
<% @ page language = " java " import = " java.util.* " pageEncoding = " GB18030 " %> <% String path = request.getContextPath(); String basePath = request.getScheme() + " :// " + request.getServerName() + " : " + request.getServerPort() + path + " / " ; %> <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < base href ="<%=basePath%>" > < title > My JSP 'index.jsp' starting page </ title > < meta http-equiv ="pragma" content ="no-cache" > < meta http-equiv ="cache-control" content ="no-cache" > < meta http-equiv ="expires" content ="0" > < meta http-equiv ="keywords" content ="keyword1,keyword2,keyword3" > < meta http-equiv ="description" content ="This is my page" > <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </ head > < body > ${student.name}-----${student.sex} < br > </ body > </ html >
值得注意的是:我们要从register.mvc来启动程序,转发到register.jsp(配置文件中的fromView属性配置),否则spring:bind标签会出现如下异常: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
部署,运行
(1)不输入姓名和性别,页面如下:
错误: 姓名必须输入 错误: 性别必须输入 错误: 性别格式错误
name: (必须输入) 错误: 姓名必须输入 sex: (必须输入,且为0或1) 错误: 性别必须输入 性别格式错误 (2)输入姓名,不输入性别,页面如下:
错误: 性别必须输入 错误: 性别格式错误
(3)不输入姓名,输入正确性别,页面如下:
错误: 姓名必须输入
(4)输入姓名,输入错误性别,页面如下:
错误: 性别格式错误
(5)都正确输入,页面如下: 11-----1