CSDN博客

img Arqui

Jakarta Commons Validator(引用)

发表于2004/10/12 13:53:00  3251人阅读

Jakarta Commons Validator

SECTION 01 Validator 总览

 

   每个应用程序都有责任确保它们插入到后台资料库的数据是合法有效的,毕竟,如果这些应用程序所依赖的数据一旦遭到了破坏,那将是灾难性的,那应用程序还能拿什么来使自己正常运转呢?比如说,使用正规关系数据库的一个应用程序,数据库中的每个字段都有自己一定的规则和约束,来保证存储在其中的数据在一定程度上的正确性。任何要使用后台资料库数据的应用程序都有责任保护它们提交的数据的完整性。
    任何试图插入或更新不符合标准的数据的操作都有可能被发现并拒绝。这种检测可能遍布在整个应用程序的每个角落,在表现层可能进行一些验证,在业务逻辑层,商业逻辑对象一般也有商业逻辑的验证,还有在后台资料库也要对数据进行检查。
    不幸的是,由于这种验证在应用程序中无处不在,造成了应用程序在一定程度上的验证数据的代码冗余。这并不是应用程序所希望的,因为这种在多处的重复劳动,使得应用程序的部署和维护要花去更多的时间。如果在整个应用程序中,这些验证规则可以重复使用,将使得应用程序更加富有弹性,换句话说就是,部署更快捷,定制更容易,程序更灵活。
Jakarta Commons 项目Validator框架简介
       Validator是由David Winterfeldt创建的开源项目,它也是Jakarta Commons的一个子项目。Commons项目主要是提供一些像Validator这样的一些可重用组件。其他著名的Commons组件还有如BeanUtils,Digester,Logging框架等。Validator 1.0版本发布于2002年11月初。
使用Validator的好处
       .使用Validator框架比一般的在应用程序的代码中定义验证规则有好多优点,如:
     .可以在一处为应用程序定义验证规则;
     .验证规则和应用程序是松耦合的;
     .服务器端和客户端的验证规则可以在同一处定义;
     .配置新验证规则或修改已有验证规则变得更加简单;
     .支持国际化;
     .支持正则表达式;
     .可以用于Web应用程序也可用于标准的Java应用程序;
     .采用声明的方法实现而不是编程实现;
除了之外,Validator最大的特征就是自身支持可插性(pluggability)。在文章的后
面你将会看到使用Validator框架内置的验证规则来更好地完成你的工作,而更重要的是,Validator框架允许你自定义验证程序,并插入到框架中。
Struts和Validator的关系
      应该指出的是Validator框架本身是因Struts框架而建立的。Validator的创建者David Winterfeldt在使用Struts的过程中发现,在许多ActionForm类中需要反复使用同一个验证规则,这样造成了大量的代码冗余。于是他决定创建Validator框架来消除这种冗余,这样Validator就诞生了。
    尽管Validator架构最初是为Struts架构而生,但它还是被设计和构造成了可以独立于Struts架构而单独使用。这一个特征使得你可以在任何的应用程序中使用这个框架,不必管它是不是Struts架构的。并不会因为你不使用Struts框架而影响Validator架构对你的应用程序作用。事实上,这就是为什么Validator是Jakarta Commons项目的一部分而不直接是Struts项目的一部分。
    现在,我们来将这个框架整合应用到像基于Struts构架这样的Web应用程序上。在文章的最后中我们再介绍如何把它应用到其他类型的应用程序中,如基于EJB的应用程序。
Validator组件概述
     Validator架构有下面这些组件组成:
     Validators;
     配置文件;
     资源绑定;
     JSP自定义标签;
     Validator Form类;
什么是Validators?
       一个Validator就是,执行一个验证规则时Validator框架调用的一个Java类。框架根据配置文件中定义的方法签名来调用这个Validaotor类。一般情况下,每个Validator类提供一个单独的验证规则,然后这些规则可以组合成更复杂的规则集。



Validate 验证, 这件事情, 写程序是非常重要的, 要先判断数据是否正确, 才让动作或事件继续执行下去, 那么, 每次都写相同的验证模式, 不如对于这个 JavaBean 的数据验证透过 XML 的设定, 如果正确则为验证成功, 发生错误则为验证失败. 对于完全没有用过 Bean Validation 的人来说, 听起来, 可能有点吃力, 不过看过例子可能就了解了.


最新版本为 v1.0.2


binary 下载
source 下载
这次请下载 source 因为有许多范例程序在其中.


SECTION 02 基本范例

大家可以查看 org.apache.commons.validator.example.* 的文件, 其实很简单, 只有 ValidateExample.java 及 ValidateBean.java 这两个程序, 还有 validator-example.xml 来作为 Bean 的验证设定. 另外 applicationResources.properties 是设定多国语言 (i18n)

大家可以直接参阅 ValidateExample, 设定 Validator 的方法其实很简单

  1. 建立 ValidatorResource Instance , 并且取得验证的配置文件
    
    ValidatorResources resources = new ValidatorResources();
    in = ValidateExample.class.getResourceAsStream("validator-example.xml");
    ValidatorResourcesInitializer.initialize(resources, in);
    			
  2. 建立要被验证的 JavaBean
    
    ValidateBean bean = new ValidateBean();
    
  3. 建立验证者, 并且告知是哪个 JavaBean 需要验证
    
    Validator validator = new Validator(resources, "ValidateBean");
    validator.addResource(Validator.BEAN_KEY, bean);
    
  4. 建立验证结果储存区, 将验证结果放入
    
    ValidatorResults results = null;
    results = validator.validate();
    
ValidatorResults 是一个 HashMap 储存 ValidateResult, 他是依照 property 为 key,

ValidatorResult result = results.getValidatorResult(propertyName);

取出 ValidatorResult; 接著用 isValid() method 去判断是否验证成功.



SECTION 03 validator-example.xml
在 global 的地方是告知, 各种情况需要用到那一个 Validator 来判断, 并且设定错误讯息, 将会参考 ApplicationResource.properties 的内容来显示, 而 form 的判断模式, 可以放入显示时候的名称, "errors.required=The {0} field is required." 如果发生验证失败, 将会把 nameForm.firstname.displayname ( 也就是写在 properties 中的 First Name ) 取代 {0} 的地方


SECTION 04 Validator 的写法

最重要的就是写 public static boolean validateXxxxx( Object bean, Field field ) 这样的 method

public class TestValidator {
                                                          
   /**
    * Checks if the field is required.
    *
    * @param 	value 		The value validation is being performed on.
    * @return	boolean		If the field isn't null and 
    *                           has a length greater than zero, 
    *                           true is returned.  
    *                           Otherwise false.
   */
   public static boolean validateRequired(Object bean, Field field) {
      String value = ValidatorUtil.getValueAsString(bean, field.getProperty());

      return !GenericValidator.isBlankOrNull(value);
   }
}  



SECTION 05 GenericValidator

目前 GenericValidator 提供了
  • isBlankOrNull(java.lang.String value) : 检查是否为空值,及去掉空白后长度是否大于零
  • isByte(java.lang.String value) : 是否可以转成 byte
  • isCreditCard(java.lang.String value) : 是否为正确的信用卡号
  • isDate(java.lang.String value, java.util.Locale locale) : 是否为有效的日期, 可依照区域别判断
  • isDate(java.lang.String value, java.lang.String datePattern, boolean strict) : 是否为有效的日期, 可输入日期格式, 是否需要完全符合
  • isDouble(java.lang.String value) : 是否可以转成 double
  • isEmail(java.lang.String value) : 是否为有效的 Email
  • isFloat(java.lang.String value) : 是否可以转成 float
  • isInRange(double value, double min, double max) : 输入数值是否在此区间 ( double )
  • isInRange(float value, float min, float max) : 输入数值是否在此区间 ( float )
  • isInRange(int value, int min, int max) : 输入数值是否在此区间 ( int )
  • isInRange(short value, short min, short max) : 输入数值是否在此区间 ( short )
  • isInt(java.lang.String value) : 是否可以转成 int
  • isLong(java.lang.String value) : 是否可以转成 long
  • isShort(java.lang.String value) : 是否可以转成 short
  • matchRegexp(java.lang.String value, java.lang.String regexp) : 是否符合输入的 Regular Expression
  • maxLength(java.lang.String value, int max) : 长度不得大于输入值
  • minLength(java.lang.String value, int min) : 长度不得小于输入值
我认为最好用的就是 matchRegexp 可以设定成各式各样的判断.


SECTION 06 Struts Validator

原本最早 , Struts-validate 是由 http://home.earthlink.net/~dwinterfeldt/revision.html 这里开始的, 2002 初开始使用 commons-validator, 就转移到 jakarta 继续开发, 你会发现 commons-validator 的开发人员都是 struts 的开发人员.


在 struts 可以透过 plug-in 设定 struts-config.xml
<plug-in classname="org.apache.struts.validator.ValidatorPlugIn">
  <set-property 
    property="pathnames" 
    value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
ValidatorPlugIn.java , 是一个实现 PlugIn ( "init()" & "destroy()" ) 的一个 Servlet

public class ValidatorPlugIn implements PlugIn {
    public void init(ActionServlet servlet, ModuleConfig config)
        throws ServletException {
		......
		initResources();
		......
	}

	protected void initResources() throws IOException, ServletException {
		......
		ValidatorResourcesInitializer.initialize(resources, bis, false);
		......
	}

    public void destroy() {
		.....
    }
}

而 ValidatorResourcesInitializer 就是属于 commons-validator 的组件,

另外的 /WEB-INF/validator-rules.xml, 包含了 client 端 javascirpt 的验证, 和 commons-validator 的验证.

最后的 /WEB-INF/validation.xml, 就是针对 FormBean 来作验证, 当然你可以自行用 commons-validator 对于 ValueObject 作验证.


SECTION 07 总结

如果不是要与 EIS ( DB layer ) 层级作处理的, 大家可以对于输入的资料通过 Validator 标准的模式, 撰写自己公司商业逻辑的 validator.下面我就举例说明

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.validator.Resources;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.validator.FieldChecks;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

/**
 * ValidationUtil Helper class for performing custom validations that
 * aren't already included in the core Struts Validator.
 *
 * <p>
 * <a href="ValidationUtil.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author
 * @version $Revision: 1.1 $ $Date: 2003/05/30 03:28:34 $
 */
public class ValidationUtil {

    private static final Log log = LogFactory.getLog(ValidationUtil.class);

    //~ Methods ================================================================

    /**
     * Validates that two fields match.
     * @param bean
     * @param va
     * @param field
     * @param errors
     * @param request
     * @return boolean
     */
    public static boolean validateTwoFields(
        Object bean,
        ValidatorAction va,
        Field field,
        ActionErrors errors,
        HttpServletRequest request) {
        String value =
            ValidatorUtil.getValueAsString(bean, field.getProperty());
        String sProperty2 = field.getVarValue("secondProperty");
        String value2 = ValidatorUtil.getValueAsString(bean, sProperty2);

        if (!GenericValidator.isBlankOrNull(value)) {
            try {
                if (!value.equals(value2)) {
                    errors.add(
                        field.getKey(),
                        Resources.getActionError(request, va, field));

                    return false;
                }
            } catch (Exception e) {
                errors.add(
                    field.getKey(),
                    Resources.getActionError(request, va, field));

                return false;
            }
        }

        return true;
    }

}

在你创建好检验功能后,你需要把他加到validation-rules.xml

<!DOCTYPE form-validation PUBLIC
          "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN"
          "http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">

<form-validation>

   <global>
   <validator name="twodatefields"
        classname="net.unihub.framework.struts.validation.ValidationUtil"
        method="validateTwoDateFields"
        methodParams="java.lang.Object,
                      org.apache.commons.validator.ValidatorAction,
                      org.apache.commons.validator.Field,
                      org.apache.struts.action.ActionErrors,
                      javax.servlet.http.HttpServletRequest"
        depends="date" msg = "errors.twodatefields">
        <javascript><![CDATA[
            function validateTwoDateFields(form) {
                var bValid = true;
                var focusField = null;
                var i = 0;
                var fields = new Array();
                oTwoDateFields = new twodatefields();
                for (x in oTwoDateFields) {
                    var field = form[oTwoDateFields[x][0]];
                    var secondField = form[oTwoDateFields[x][2]("secondProperty")];
     var datePattern = oTwoDateFields[x][2]("datePatternStrict");

                    var value;
                    var secondValue;
                    if (field.type == "select-one") {
                        var si = field.selectedIndex;
                        value = field.options[si].value;
                        secondValue = secondField.options[si].value;
                    } else {
                        value = field.value;
                        secondValue = secondField.value;
                    }   
                      
                    if ((field.type == 'text' ||
                        field.type == 'textarea' ||
                        field.type == 'select-one' ||
                        field.type == 'radio' ||
                        field.type == 'password') &&
                       (datePattern.length > 0) &&
                       (value.length > 0) &&
                       (secondValue.length > 0)) {

                        var MONTH = "MM";
                        var DAY = "dd";
                        var YEAR = "yyyy";
                        var orderMonth = datePattern.indexOf(MONTH);
                        var orderDay = datePattern.indexOf(DAY);
                        var orderYear = datePattern.indexOf(YEAR);
                        var fromdt = new Date();
                        var todt = new Date();
                        fromdt.setYear(value.substr(orderYear,4));
                        fromdt.setMonth(value.substr(orderMonth,2)-1);
                        fromdt.setDate(value.substr(orderDay,2));
                        todt.setYear(secondValue.substr(orderYear,4));
                        todt.setMonth(secondValue.substr(orderMonth,2)-1);
                        todt.setDate(secondValue.substr(orderDay,2));

      if (todt < fromdt) {
                            if (i == 0) {
                                focusField = field;
                            }
                            fields[i++] = oTwoDateFields[x][1];
                            bValid = false;
                        }
                    }
                }

                if (fields.length > 0) {
                    focusField.focus();
                    alert(fields.join('/n'));
                }

                return bValid;
            }]]></javascript>     
      </validator>     
 </global>

</form-validation>

阅读全文
0 0

相关文章推荐

img
取 消
img