Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1180|回复: 0

[struts学习]强大的有效性验证组件apache Jakarta commons-validat

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-11 02:01:25 | 显示全部楼层 |阅读模式
    强大的有效性验证组件apache Jakarta commons-validator
      来源:
         http://blog.hnpj.com/more.asp?name=jmythic&id=138
         作者:Linux.J.Su  

    一. 前言
        本文较详尽地介绍了jakarta开源项目的子项目之一commons-validator,版本是1.0.2。它使用了一个xml文件来定义针对用户输入的数据验证功能,整个验证体系提供了很强的扩展性,使得开发者可以开发自己的验证函数加入到这个验证体系中来。它对web应用程序提供了客户端javascript验证和服务端验证的两种选择,但是它只是一个验证体系,有些东西还需要自己开发特别是validatoraction的开发,不过有了项目源代码及其例子,还有struts这个优秀的开源项目的示范,使用好commons-validator验证体系应该是挺容易的。本文就这个验证体系作了些探讨,希望对大家有用!  

      
      
       
       
       

       
      

    二. 用户问题
        我们在开发信息系统时,用户界面往往是一个很容易忽视的但是确是相当重要的地方。我们有好多关于编写后端代码的设计模式,现在我们还拥有commons-validator这样的优秀验证体系对付用户界面的用户千变万化的输入可能。输入验证关乎到整个信息系统的强壮性,因为恶意的输入数据可能导致信息系统崩溃;输入验证还关乎到信息系统的友好性,因为不能给用户提供正确的输入导引经常搞得使用者手足无措,最后只有悲愤而去。  

    三. 简单分析
        通过对上面用户问题的描述,我们可以简单分析一下验证体系的基本特性:  

        验证体系应该具有良好的可扩展性,可以让信息系统开发者开发自己的验证功能,以满足特殊系统的验证要求。验证体系应该能显示准确的验证错误信息,用以帮助使用者纠正错误,而且错误信息应该是外在可配置的,改变相应的错误信息不需要修改源代码。  
    对于web信息系统来说,应该能支持客户端验证和服务端验证两种方式。  


    四. 代码样例
         虽然common-validation是为web应用写的验证体系,它同时也能用在java应用程序中,为了把注意力放在验证系统的介绍上,下面的验证样例使用java应用程序来表演。  

    1. 定义验证规则
        验证规则是一个xml文件,定义了需要验证的表单,及其表单的各个字段以及字段的验证要求,另外validator元素是用来完成各个字段的验证要求的。本例定义了一个输入表单nameForm及其两个字段,两个字段都必须提供,而且age字段还必须是整数;还定义了两个验证动作int和required,分别满足整数要求和必须提供的要求:  

    myvalidator-example.xml
    <?xml version="1.0" encoding="iso-8859-1"?>
    <form-validation>
       <global>      
          <validator name="int"  
                     classname="org.i505.validator.MyTypeValidator"  
             method="validateInt"     
             methodParams="java.lang.Object,org.apache.commons.validator.Field"
             msg="errors.int"/>     
         <validator  name="required"         
                     classname="org.i505.validator.MyValidator"   
                     method="validateRequired"            
                     methodParams="java.lang.Object,org.apache.commons.validator.Field"     
                     msg="errors.required"/>  
    </global>
    <formset>  
    <form name="nameForm">  
         <field property="username"  depends="required">     
             <arg0 key="nameForm.username.displayname"/>     
         </field>     
         <field  property="age" depends="required,int">        
             <arg0 key="nameForm.age.displayname"/>      
         </field>   
    </form>  
    </formset>   
    </form-validation>

       
    2. 编写消息资源文件
        commons-validator的消息资源包括两大部份,第一部分是包括了参数占位符的validatoraction对象的消息,第二部分是各个输入表单输入数据的显示信息,用作验证失败时的信息显示。本例中值包括了一个输入表单的显示信息:  

    myapplicationResources.properties

    # validatoraction对象的消息
    errors.required=必须提供{0}字段!
    errors.int= {0}字段必须是整数!

    # nameForm输入表单的各个输入数据的显示信息
    nameForm.username.displayname=姓名
    nameForm.age.displayname=年龄

    3. 编写validatorAction  
         我们从验证定义规则文件中可以看出validator元素定义的int和required validatorAction分别使用了org.i505.validator.MyTypeValidator和org.i505.validator.MyValidator两个类,这个元素还定义了它们使用的验证方法validateInt和validateRequired以及方法的参数类型列表。下面是这两个类的代码:  


    package org.i505.validator;import  
    org.apache.commons.validator.Field;
    import org.apache.commons.validator.GenericTypeValidator;
    import org.apache.commons.validator.ValidatorUtil;
    public class MyTypeValidator {  
          public static Integer validateInt(Object bean, Field field) {   
                     String value = ValidatorUtil.getValueAsString(bean, field.getProperty());
                     Integer x= GenericTypeValidator.formatInt(value);   
                      return x;   
          }
    }                                                         

    package org.i505.validator;
    import org.apache.commons.validator.Field;
    import org.apache.commons.validator.GenericValidator;
    import org.apache.commons.validator.ValidatorUtil;   
    public class MyValidator {            
              public static boolean validateRequired(Object bean, Field field) {   
                     String value = ValidatorUtil.getValueAsString(bean, field.getProperty());  
                     return !GenericValidator.isBlankOrNull(value);   
    }
    }                                                         

       
    4. 编写javabean  
         commons-validator是一个针对web应用的输入验证体系,验证规则中的form定义是针对HTML form表单的,但是common-validator在内部验证时需要javabean。这个javabean的各个属性就代表了html form表单的输入控制。所以针对前面的验证规则,我们实现的javabean需要定义两个属性:age和username,代码如下:  

    public class ValidateBean extends Object {
             String username;String age;   
             public void setUsername (String username) {
                    this. username = username;   
             }   
             public String getUsername () {
                    return this.username;   
             }   
             public void setAge (String age) {
                    this.age = age;  
             }  
             public String getAge () {
                    return this.age;   
             }  
             public String toString() {
                   return "{ username =" + this.username + ", age=" + this.age + "}";   
             }
    }

       注意,这个验证BEAN的age属性的类型是字符串型的,因为它只是代表了html form表单的输入控制的值,原始的用户输入数据基本上都可以用String来表示,如果我们申明age属性的类型时整数型,则我们在html form表单的值到BEAN的age属性就经过了一次类型转换,这个早于我们的整型验证,所以可能有产生类型转换错误的危险。  

    5. 编写验证主程序

    编写验证主程序主要有下面五步:

    a、创建和处理ValidatorResources对象,这要借助于ValidatorResourcesInitializer类利用验证规则定义文件初始化这个对象。  
    b、创建要验证的bean对象  
    c、用验证规则定义文件中定义的某个form创建validator对象,并且告诉这个对象要验证的bean对象。  
    d、运行validator对象的validate()方法实际验证bean对象  
    e、打印验证结果  

        下面是依据上面所述步骤编写的实例代码,代码中进行了三次验证,第一次是验证两个属性都是空的bean对象,第二次是age属性不合法的bean对象,第三次是两个属性都合法的bean对象:  

    (源文件请从本站下载)
    public static void main(String[] args) throws IOException, ValidatorException {   
             InputStream in = null;   
             try {            
                     ValidatorResources resources = new ValidatorResources();        
                     in = ValidateExample.class.getResourceAsStream("myvalidator-example.xml");   
                     ValidatorResourcesInitializer.initialize(resources, in);      
                     ValidateBean bean = new ValidateBean();            
                     Validator validator = new Validator(resources, "nameForm");   
                     validator.addResource(Validator.BEAN_KEY, bean);        
                     ValidatorResults results = null;           

                     results = validator.validate();        
                     printResults(bean, results, resources);   

                     bean.setUsername("龚永生");            
                     bean.setAge("很年轻");           
                     results = validator.validate();   
                     printResults(bean, results, resources);  
       
                     bean.setAge("28");     
                     results = validator.validate();   
                     printResults(bean, results, resources);     
             }
             finally {      
                     if (in != null) {  
                             in.close();      
                     }
             }
    }

    6. 打印验证结果

        打印验证结果可能是验证体系中最复杂的一部分,因为它涉及到验证文件和消息资源文件,涉及到好多对象以及它们复杂的关系。特别需要指出的是错误消息文本的显示。下面的代码包括三个部分:第一部分是使用资源文件生成ResourceBundle对象,注意你的资源文件必须在classloader能找到的地方;第二部分是实际打印验证结果;第三部分是个显示中文消息的函数。  

    validator对象的validate()方法会把验证结果保存到其返回的ValidatorResults对象中,它保存了bean对象被验证的每个属性的各种验证要求的验证结果对象ValidatorResult,首先我们可以获取bean对象对应的验证文件定义的form,从而得到相应的消息键和其它信息,而且通过这些信息从ValidatorResults对象中获取相应的ValidatorResult对象,利用ValidatorResult对象isValid函数可以判断验证的成功与否,如果验证没通过,可以使用form的信息显示错误消息文本。  


          private static ResourceBundle apps =
              ResourceBundle.getBundle("org.i505.validator.myapplicationResources");  
       
              public static void printResults(      
              ValidateBean bean,      
              ValidatorResults results,     
              ValidatorResources resources) {   
                     boolean success = true;   
                     Form form = resources.get(Locale.getDefault(), "nameForm");   
                     System.out.println("

    验证:");   
                     System.out.println(bean);   
                     Iterator propertyNames = results.get();     
                     while (propertyNames.hasNext()) {     
                       String propertyName = (String) propertyNames.next();      
                       Field field = (Field) form.getFieldMap().get(propertyName);   
                       String prettyFieldName = getGBKMsg(apps.getString(field.getArg0().getKey()));   
                       ValidatorResult result = results.getValidatorResult(propertyName);     
                       Map actionMap = result.getActionMap();      
                       Iterator keys = actionMap.keySet().iterator();   
                       while (keys.hasNext()) {      
                         String actName = (String) keys.next();      
                         ValidatorAction action = resources.getValidatorAction(actName);                                   
                         System.out.println(         
                                             propertyName                  
                                             + "["                    
                                             + actName               
                                             + "] ("               
                                             + (result.isValid(actName) ? "验证通过" : "验证失败")      
                                             + ")");        
                                             if (!result.isValid(actName)) {     
                                                success = false;               
                                                String message = getGBKMsg(apps.getString(action.getMsg()));      
                                                Object[] args = { prettyFieldName };              
                                                System.out.println(                 
                                                         "错误信息是: "                    
                                                         + MessageFormat.format(message, args));      
                                            }      
                                 }        
                         }     
                         if (success) {   
                                      System.out.println("表单验证通过");  
                         }
                         else {
                                      System.out.println("表单验证失败");  
                         }
                  }   

                  public static String getGBKMsg(String msg){   
                         String gbkStr="";     
                         try {
                              gbkStr=new String(msg.getBytes("iso-8859-1"),"gbk");
                         }
                         catch (UnsupportedEncodingException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                         }
                         return gbkStr;  
                  }

       


    验证结果如下:

    D:java>java   ValidateExample


    验证:
    { username =null, age=null}
    age[required] (验证失败)
    错误信息是: 必须提供年龄字段!
    username[required] (验证失败)
    错误信息是: 必须提供姓名字段!
    表单验证失败


    验证:
    { username =龚永生, age=很年轻}
    age[int] (验证失败)
    错误信息是: 年龄字段必须是整数!
    username[required] (验证通过)
    表单验证失败


    验证:
    { username =龚永生, age=28}
    age[int] (验证通过)
    username[required] (验证通过)
    表单验证通过

    D:java>


    五. 内部剖析(略)  

      
      
       
       

         
       

         
       
      
      

    源码下载:http://file.javaxxz.com/2014/10/11/020124578.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 13:34 , Processed in 0.297017 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表