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 >
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
<% ... @ 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
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配置文件中注入
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", "姓名必须输入");
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字段的正则验证
errors.rejectValue("sex", "not confirmat", null,"性别格式错误");
}
配置文件:
web.xml
< 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>
来定义验证框架需要验证的类(这个属性对我们在页面上显示错误信息有用)
< 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对象中的所有错误信息
< 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信息
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
<% ...
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)不输入姓名和性别,页面如下:
错误: 姓名必须输入
错误: 性别必须输入
错误: 性别格式错误
错误: 性别必须输入
错误: 性别格式错误
错误: 姓名必须输入
(4)输入姓名,输入错误性别,页面如下:
错误: 性别格式错误
11-----1