<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)不输入姓名和性别,页面如下:
错误: 姓名必须输入
错误: 性别必须输入
错误: 性别格式错误
(2)输入姓名,不输入性别,页面如下:
错误: 性别必须输入
错误: 性别格式错误
(3)不输入姓名,输入正确性别,页面如下:
错误: 姓名必须输入
(4)输入姓名,输入错误性别,页面如下:
错误: 性别格式错误
(5)都正确输入,页面如下:
11-----1