实战Spring MVC 表单验证框架

 

< 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)输入姓名,不输入性别,页面如下:

错误: 性别必须输入
错误: 性别格式错误

name: (必须输入)
sex: (必须输入,且为0或1) 错误: 性别必须输入 性别格式错误
(3)不输入姓名,输入正确性别,页面如下:

错误: 姓名必须输入

name: (必须输入) 错误: 姓名必须输入
sex: (必须输入,且为0或1)

(4)输入姓名,输入错误性别,页面如下:

错误: 性别格式错误

name: (必须输入)
sex: (必须输入,且为0或1) 错误: 性别格式错误
(5)都正确输入,页面如下:

11-----1

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值