Struts2之验证框架

1:Struts2提供了验证框架,功能强大而且简单易用,帮助用户做了很多事情,使得用户不必从头开发。那么一个好的验证框架需要考虑哪些因素呢?

   *验证功能的复用性

    比如都是对一个int数据类型的验证,验证的是它的数据范围,如果验证功能抽象的好,就可以复用同样的验证功能,省去重复开发的麻烦。

   *验证功能的可扩展性

      是不是可以自己扩展验证功能,并保证扩展功能和原有的框架功能一样使用。

    *验证与业务逻辑分离

      在业务开发时,可能需要在业务逻辑不变的情况下修改验证逻辑,比如某个网站要求大于18周岁的公民才能注册,随着业务的开展,要修改为大于15岁的公民才能注册,很显然,这个时候,注册逻辑本身没有改变,但是验证逻辑发生了变化,那么,分离的验证逻辑可以保证在修改验证逻辑的时候,不会为业务逻辑带来麻烦。

 

 2:验证框架入门

     验证需求:用户注册时只需要填写自己的账号、姓名、年龄,其中,账号和姓名必须填写,年龄要求必填而且在18岁以上。

     简单示例:

     页面:register.jsp

      

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>




Struts2验证框架


   
       
       
       
       
   


Action的内容:

   

package com.capinfotech.action;

import com.capinfotech.model.UserModel;

public class RegisterAction extends BaseAction {

	private UserModel user = new UserModel();

	public UserModel getUser() {
		return user;
	}

	public void setUser(UserModel user) {
		this.user = user;
	}
	
	public String execute() {
		System.out.println("传人的数据为:" + user.toString());
		return SUCCESS;
	}
	
}

struts.xml的内容:

 


            /validation/success.jsp
            /validation/register.jsp
       


验证框架的配置文件RegisterAction-validation.xml




    
        
            请输入账号
        
    
    
    
        
             请输入姓名
        
    
    
    
        
           18
           年龄必须在18岁以上
        
    


输出结果:

   

   


验证执行时机:验证发生在execute方法运行之前,在Struts2的params拦截器已经把请求的参数反射的设置到Action的属性之后,所以,验证框架实际上验证的是值栈里面的内容。

验证的结果:如果用户输入的参数完全满足验证条件,则会继续执行execute方法,如果用户输入的参数不满足验证条件,注意:3个验证条件只要有一个验证通不过,就会跳转到这个Action所配置的名为input的Result,所以在struts.xml里最好配置一个名为input的result


3:验证框架的运行原理

   *首先看一下defaultStack包括的拦截器

    

 
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                  dojo\..*,^struts\..*
                
                
                
                    input,back,cancel,browse
                
                
                    input,back,cancel,browse
                
            

params拦截器和conversionError拦截器在validation拦截器的前面。

params拦截器将请求的参数反射的设置到Action的属性,当然,这时候有可能出错。

conversionError拦截器验证Action的属性是否符合条件。

validation会根据配置文件的配置进行验证,其实,validation验证的是值栈中的内容,而值栈中的内容则来源于请求的参数部分。


验证框架运行流程如下图所示:




4:验证器类型

    *验证谁

    *使用什么条件进行验证

    *不满足条件显示什么结果

    *不满足验证条件时,显示的结果出现在页面的什么位置


    *字段验证器:用来验证提交的表单内的单个字段

    

 
        
           18
           年龄必须在18岁以上,您输入的年龄为${user.age}
        
    
   *field表示是字段验证器,name指示验证哪个字段,每一个field-validator元素是这个字段的一种验证条件,type指示的是验证器,验证错误时,message表示的消息会返回,message元素存在key属性,可以用来引用国际化信息


另一种写法:

  

 
        user.age
        18
        年龄必须在18岁以上,您输入的是${user.age}
    

    *动作验证器

    动作验证器应用于整个动作(Action),一般用于验证提交的表单内的多个字段之间的关系,当然也可以验证单个字段

   假定要求输入的账号也为数字,并要求输入的age的值要大于账号的值,那么在验证文件里,可以按照如下写法:

   

 
        
          
        
        姓名的长度要比账号的长度小
    


 
  

界面输出如下:

   



5:内建验证器

     


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

   *类型转换错误验证器(conversion)

   *整数验证器(int) 有两个参数min和max

   *长整型和短整形验证器short和long

   *日期验证器(date),有两个参数min和max,需要使用同一的格式,比如用MM/DD/YYYY的格式

   *双精度浮点验证器(double)

    用来验证一个双精度浮点型参数是否在指定的范围内,如果一个已经被成功转换为double的属性不在验证器指定的范围内,double验证器就会报错。

       可以接受的参数:

          *minInclusive用来指定可接收范围的最小值,包含指定值

          *maxInclusive用来指定可接受范围的最大值,包含给定值

          *minExclusive用来指定可接受范围的最小值,不包含给定值

           *maxExclusive用来指定可接受范围的最大值,不包含给定值

    *邮件验证器(email)

    *URL验证器(url)

    *必填验证器(required)

    *必填字符串验证器(requiredstring):用来验证一个字符串是否非空,即不为null,且长度大于0,trim:是否去掉字符串两边的空白,默认为true

    *字符串长度验证器(stringlength):用来验证一个字符串的长度是否在指定的长度内

           可以接受的参数:

                   *maxLength  minLength   trim

     *正则表达式(regex): 用来验证一个字符串是否符合一个正则表达式的要求

            可以接受的参数:

                   *expression: 必填参数,正则表达式

                   *caseSensitive:是否检查大小写

                   *trim:是否去掉字符串两边的空白,默认为true

       *字段表达式验证器(fieldexpression)和表达式验证器(expression)

       *访问者验证器(visitor)

          visitor验证器用于验证Action中的复合属性,可以直接把验证信息放到域对象中去注册,这样就使得同包内的不同Action在验证同一个域对象时,不用注册重复的验证信息。

        两个属性:

            *context:引用的域对象验证信息文件上下文名

            *appendPrefix: 是否在错误信息中添加元素指定的前缀

   

6:自定义验证器

       实现一个不接受中文字符的验证器,比如,在一个网站上进行注册,在输入账号的时候,必须输入英文字符或者是数字,而不接受中文字符,同时还要求验证器可以分辨以下3种情况:

      *全是非中文字符

      *全是中文字符

      *既有中文字符,又有非中文字符

  

    实现自定义的验证器

       要验证一个字符串是否含有中文字符,可以使用比较字符串的字节数和字符数的方式,也就是比较byte的长度和char的长度

      调用字符串的length方法,可以返回字符串的长度,这时候无论是中文字符还是英文字符都会按照一个字符来返回,也就是得到了字符串的字符数

      如果把字符串转换成byte[], 然后取其length, 就可以得到字符串的字节数,这时候,中文字符在数组中占两个位置而英文字符在数组中占用一个位置

     因此,比较字符串的字节数和字符数,就可以知道字符串中是否有中文字符了,如果字节数大于字符数,那么肯定包含了中文字符

    实现类:

   

package com.capinfotech.validator;

import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class ChineseValidator extends FieldValidatorSupport {

	/**
	 * 表示是否包含有中文,有3中模式
	 * none:没有中文
	 * some:含有中文字符,取默认值
	 * all:全是中文字符
	 */
	private String mode = "some";
	
	public void setMode(String mode) {
	     this.mode = mode;	
	}
	
	@Override
	public void validate(Object object) throws ValidationException {
  
		//获得字段名
		final String fieldName = this.getFieldName();
		//获得字段值
		final String fieldValue = (String)this.getFieldValue(fieldName, object);
		//获得字节数
		final int bytes = fieldValue.getBytes().length;
		//获得字符数
		final int chars = fieldValue.length();
		
		System.out.println("bytes:" + bytes);
		System.out.println("chars:" + chars);
		
		if(mode.equals("none")) {
			//要求全是非中文字符
			//所以字节数和字符数,两个数字必须相等,不相等则出错
			if(chars != bytes) {
				this.addFieldError(fieldName, object);
			}
		} else if(mode.equals("some")) {
			//现在要求包含有中文字符
			if(chars == bytes || chars * 2 == bytes) {
				this.addFieldError(fieldName, object);
			}
		} else if(mode.equals("all")) {
			if(chars * 2 != bytes) {
				this.addFieldError(fieldName, object);
			}
		}
	}
}

在src下新建一个validators.xml文件,并把默认的验证器也要包含进来:






    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    



使用chinese验证器:


        
             请输入姓名
        
        
        
             none
             用户账号,只能输入非中文的字符
        
    

输出结果页面:



8:引用验证器返回的错误信息

      两种方式:

      *对于字段验证信息错误来说,在使用xhtml风格的时候,标签会将这个字段的错误信息显示在这个文本框的上边

      *可以使用标签来将字段验证错误的错误信息显示在指定位置,如果不指定其filedName属性则会显示所有的错误信息,如果指定了fieldName属性

     则会显示指定字段的错误,对于动作验证错误,可以使用标签,它会把所有的动作验证错误显示在指定的位置


9:验证器框架的查找顺序

     *父类-validation.xml

      *父类-别名-validation.xml

      *接口-validation.xml

       *接口-别名-validation.xml

       *Action类名-validation.xml

        *Action类名-别名-validation.xml

其实就是按照父类-->接口-->Action类的顺序


10:验证器短路

     当一个字段有多个验证条件的时候,在第一次出现验证错误后,就立即终止验证,后续对这个字段的验证就不再执行了,这就是验证器短路。

    配置:在验证器的配置上,设置short-circuit属性,其值为true。它可以设置在上,也可以设置在元素上。















你可能感兴趣的:(Struts2)