Validator验证框架

 

Validator验证框架 javascript

1、Validator框架的优点

       Validator框架是一个Struts插件,最初由David Winterfeldt设计并实现。Validator框架从Struts 0.5时代就可使用,但那时Validator框架只是被捐助的一个jar包。Apache组织为了使开发人员更方便地使用Validator框架,决定从Struts1.1开始,将Validator框架做为Struts的一部分同Struts一块儿发布。 html

Validator框架能够在XML文件中配置验证规则和验证对象。所以,使用Validator框架能够无需在ActionForm的子类中覆盖validate方法就能够很方便地验证客户端的提交数据。因为Validator框架内置了不少预约义的验证机制,如验证某个属性是否存在,验证EMail是否合法等。因此在通常状况下,只须要配置XML文件就能够知足咱们的验证需求。 java

在使用Validator框架时,就会发现这种方式要比直接使用validate方法进行验证会给咱们带来以下的好处: web

1.  更容易维护。 因为验证信息能够被放置在同一个配置文件中,所以,咱们能够更容易地来维护这些验证信息。 正则表达式

2.  标准化。因为不少简单的验证都是相同的。如用户名和密码都要求由字母、数字以及下划下组成。若是将这些验证都写在validate方法中,对这些验证进行标准化很是困难。而在Validator框架中的这些验证机制都是预先定义的,所以,标准化相同的验证对于Validator框架来讲将是一件很是轻松的事。 sql

3.  避免重造轮子。虽然一些验证很简单,但若是想正确实现它们也是很是困难的。一个典型的例子是验证EMail地址的格式。若是这个验证要想天衣无缝,就必须按着RFC-2822规范的要求来验证EMail地址。而若是咱们使用Validator框架,就无需再重造轮子来验证EMail地址了。 shell

4.  减小重复代码的数量。因为Validator框 架提供了不少预约义的验证,所以,咱们能够避免本身写不少重复的代码进行验证。固然,咱们也能够将大量使用的验证封装在类的方法中,这些虽然能够避免大量的重复劳动,但这就意味着咱们团队的新成员要使用这些被封装的验证方法以前必须先学习它们。而最糟糕的状况是不少开发人员可能会忘记使用这些由其余成员实 现的验证库,而本身从新编写具备一样功能的验证库。固然,这一切若是使用Validator框架就均可以获得解决。 apache

    5.  客户端和服务端验证自动切换。咱们只须要简单地在JSP页面中放一个单独的<html::javascript/>元素就能够将服务端的验证转换为客户端验证(基于JavaScript的验证)
   
虽然Validator框架的预约义验证已经能够知足大多数的验证需求了,但在某些特殊状况下,这些预约义验证就没法知足咱们的需求了,为此,Validator框架也为开发人员提供了扩展验证机制的功能。这也使得Validator框架能够完成更复杂的验证工做。

数组

2、配置和使用Validator框架 浏览器

 1.  安装Validator框架

    因为ValidatorStruts的一个插件,所以,就须要在struts-config.xml文件中按着Struts插件的方式来安装Validator框架。打开struts-config.xml文件,在<struts-config>元素中加入一个<plug-in>子元素,以下面的代码所示:

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validator.xml" />
</plug-in>     

其中<set-property>元素设置了插件中使用的pathnames属性的值。在pathnames属性值中包含了两个xml文件。

1validator-rules.xml:在这个文件中声明了Validator框架的预约义验证。这个文件能够在Struts的发行包的lib目录中能够找到这个文件。在使用MyEclipseWeb工程添加Struts功能后,会自动将这个文件加到WEB-INF目录中。

2validator.xml:这个文件定义了要验证的对象。实际上,在这个文件中,包含了一个或多个ActionForm的子类及其要验证的属性和验证规则。所以,这个文件就至关于validate方法。在Validator框架中,能够有多个定义验证对象的xml文件(能够将不一样的ActionForm的子类分散到不一样的xml文件中),中间用逗号(,)隔开,以下面的代码所示:

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validator1.xml,
                                             /WEB-INF/validator2.xml, /WEB-INF/validator3.xml"
 />
</plug-in>     

2.  使用Validator框架的一个例子

   
在本节将举一个例子来演示如何使用Validator框架来验证数据。咱们须要按着以下的六步来完成这个例子:

【第1步】创建FirstValidatorForm类(ValidatorForm的子类)

<samples工程目录>\src\actionform目录中创建一个FirstValidatorForm.java文件,代码以下:

  package actionform;
  
import org.apache.struts.validator.ValidatorForm;
  
public class FirstValidatorForm extends ValidatorForm  // 必须从ValidatorForm继承
  {
      
private String name;
      
private String age;
      
private String email;
      
public String getName()
      {
          
return name;
      }
      
public void setName(String name)
      {
          
this.name = name;
      }
      
public String getEmail()
      {
          
return email;
      }
      
public void setEmail(String email)
      {
          
this.email = email;
      }
      
public String getAge()
      {
          
return age;
      }
      
public void setAge(String age)
      {
          
this.age = age;
      }
  }

    要注意的是,要想使用Validator框架验证数据,Form类就必须从ValidatorForm继承,而不能从ActionForm继承。这是由于ValidatorForm类是从ActionForm继承的,在ValidatorForm类中已经覆盖了validate方法来自动进行验证工做,所以,咱们在ValidatorForm的子类中就不用写validate方法了。

【第2步】创建ValidatorAction类(Action的子类)
   
<samples工程目录>\src\action目录中创建一个ValidatorAction.java文件,代码以下:

  package action;
  
import javax.servlet.http.*;
  
import org.apache.struts.action.*;
  
public class ValidatorAction extends Action
  {
      
public ActionForward execute(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      {
          response.setCharacterEncoding("GBK");
          
try
          {
              response.getWriter().println("
验证成功!");
          }
          
catch (Exception e)
          {
          }
          
return null;
      }
  }

        ValidatorAction类是一个空的Struts动做类(除了输出一行“验证成功!”字符串)。这个动做是为了正常运行含有Struts元素的JSP程序所编写的。在之后的代码中会常用到这个Struts动做类。

【第3步】配置struts-config.xml文件

    配置FirstValidatorFormValidatorAction的代码以下所示

<form-bean name="firstValidatorForm" type=" actionform.FirstValidatorForm" />
<action name="firstValidatorForm" path="/firstValidator" scope="request" type=" action.ValidatorAction"  input="/firstValidator.jsp"/>       

其中firstValidator.jsp是用户录入信息的界面,也是显示错误信息的界面。

【第4步】创建firstValidator.jsp
   
Web根目录创建一个firstValidator.jsp文件,代码以下:

  <%@ page pageEncoding="GBK"%>
  
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
  
<html>
    
<head>
      
<title>第一个Validator程序</title>
    
</head>
    
<body>
      
<html:form action="firstValidator" >
         
  名:
<html:text property="name" />&nbsp;&nbsp;<font color="red"><html:errors property="name"/></font><p>
         
  龄:
<html:text property="age"/>&nbsp;&nbsp;<font color="red"><html:errors property="age"/></font><p>
       EMail

<html:text property="email"/>&nbsp;&nbsp;<font color="red"><html:errors property="email"/></font><p>
              
<html:submit value="提交"/>
      
</html:form>  
    
</body>
  
</html>

    firstValidator.jsp中能够看出,无论是否使用Validator框架进和验证,对于JSP代码来讲是彻底同样的。仍然是使用<html:errors>元素来显示错误信息。但要注意,在使用Validator框架时,<html:errors>标签的property属性的值就是所对应ValidatorForm的子类的属性名。

【第5步】配置validator.xml文件
   
在本例中只使用了一个XML文件(validator.xml)来配置要验证的对象。validator.xml的代码以下:

  <?xml version="1.0" encoding="GBK" ?>
  
<!DOCTYPE form-validation PUBLIC
   "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
            "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd"
>
  
<form-validation>
      
<formset>
          
<form name="firstValidatorForm">
              
<field property="name" depends="required,maxlength,minlength,mask">
                  
<msg name="required" key="error.name.blank" />
                  
<msg name="minlength" key="error.name.minLength" />
                  
<msg name="maxlength" key="error.name.maxLength" />
                  
<msg name="mask" key="error.name.alphanum" />
  
                  
<arg name="minlength" key="${var:minlength}" position="0" resource="false" />
                  
<arg name="maxlength" key="${var:maxlength}" position="0" resource="false" />
                  
<var>
                      
<var-name>minlength</var-name>
                      
<var-value>5</var-value>
                  
</var>
                  
<var>
                      
<var-name>maxlength</var-name>
                      
<var-value>10</var-value>
                  
</var>
                  
<var>
                      
<var-name>mask</var-name>
                      
<var-value>^[a-zA-Z0-9]*$</var-value>
                  
</var>
              
</field>
              
<field property="age" depends="required,integer,intRange">
                  
<msg name="required" key="error.age.blank" />
                  
<msg name="integer" key="error.age.integer" />
                  
<msg name="intRange" key="error.age.intRange" />
  
                  
<arg name="intRange" key="${var:min}" position="0" resource="false" />
                  
<arg name="intRange" key="${var:max}" position="1" resource="false" />
                  
<var>
                      
<var-name>min</var-name>
                      
<var-value>18</var-value>
                  
</var>
                  
<var>
                      
<var-name>max</var-name>
                      
<var-value>60</var-value>
                  
</var>  
              
</field>
              
<field property="email" depends="required,email">
                  
<msg name="required" key="error.email.blank" />
                  
<msg name="email" key="error.email.invalid" />
              
</field>
          
</form>
      
</formset>
  
</form-validation>

        validator.xml文件中的全部配置都放到<form-validation>元素中。在<form-validation>元素中有一个<formset>子元素,这个元素能够定义多个<Form>元素,这个元素用来定义要验证的ValidatorForm类的子类。其中name属性值就是<form-bean>元素中的name属性值。

<field>元素用来定义某个属性的约束条件,如第一个<field>元素定义了name属性必须存在(required)、必需要知足最小长度(minlength)和最大长度(maxlength)以及还要经过mask所指的正则表达式的验证。

<msg>元素用来定义出错信息在属性文件中的Key(全部的出错信息都在属性文件中)。<arg>元素用来向出错信息中的参数传递参数值。<var>元素用来定义变量名和变量值。

详解:

 

<!--
     验证规则配置文件的DTD,版本 1.1.3
     容许你开始处的DOCTYPE元素以后(固然DOCTYPE元素要在"xml"声明以后),
     使用XML来配置你的验证文件:
     <!DOCTYPE form-validation PUBLIC
      "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
      " http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
     $Id: validator_1_1_3.dtd,v 1.1.2.2 2004/04/06 22:20:36 rleland Exp $
-->
 
<!--
      "form-validation" 元素是配置文件结构的根元素,
      而且包含了全部其余内嵌配元素及其配置。
-->
<!ELEMENT form-validation (global*, formset*)>

<!--
     在"global"元素中定义的元素都是全局的。能够在文件
     其余地方被引用
-->
<!ELEMENT global (validator*, constant*)>

<!--
      "validator"元素用来定义验证器,这些验证器能够被在formset元素中
      field元素所引用。
      元素:
        validator          定义一个新的验证器
        javascript         在客户端验证使用的javascript源代码
      属性:
          name             验证(器)的名称
          classname        处理服务器端验证的类的类名
          method           服务器端处理验证的方法名
          methodParams     要传递到服务器端验证方法的参数,多个参数用逗号分开
          msg              验证失败时在消息资源中绑定的消息资源key。
                          若是不但愿使用默认的key,能够重写它的值以指向所需的消息资源。
          depends          在调用证以前所须要调用的其余验证的列表,多个用逗号分隔。
                          若是想要进行当前验证,那么列表中的全部验证必须成功。
          jsFunctionName   返回某一类型全部字段的JavaScript函数的函数名。
          jsFunction       被传递到对表单进行表单验证的JavaScript函数的函数名。
-->
<!ELEMENT validator (javascript?)>
<!ATTLIST validator name CDATA #REQUIRED>
<!ATTLIST validator classname CDATA #REQUIRED>
<!ATTLIST validator method CDATA #REQUIRED>
<!ATTLIST validator methodParams CDATA #REQUIRED>
<!ATTLIST validator msg CDATA #REQUIRED>
<!ATTLIST validator depends CDATA #IMPLIED>
<!ATTLIST validator jsFunctionName CDATA #IMPLIED>
<!ATTLIST validator jsFunction CDATA #IMPLIED>

<!--
      "javascript"元素定义了客户端执行验证的JavaScript函数.
-->
<!ELEMENT javascript (#PCDATA)>

<!--
      "constant"元素定义了能够在"field"元素中替代参数的静态常量值。
      "constant-name"和"constant-value"元素定义了常量引用id和替代值。
-->
<!ELEMENT constant (constant-name, constant-value)>
<!ELEMENT constant-name   (#PCDATA)>
<!ELEMENT constant-value (#PCDATA)>

<!--
       "formset"定义了一个本地表单集合。若是对于指定的地区(国际化用),那么就只能重写
       相应字段的验证。由于本地化是随地区而定的,因此若是须要本地化,就要改动language或
       country属性或者二者都改。
-->
<!ELEMENT formset (constant*, form+)>
<!ATTLIST formset language CDATA #IMPLIED>
<!ATTLIST formset country CDATA #IMPLIED>
<!ATTLIST formset variant CDATA #IMPLIED>

<!--
      "form"元素定义了一个须要验证的字段集。name属性与web应用中表单
      的相应字段名相同。
-->
<!ELEMENT form (field+)>
<!ATTLIST form name CDATA #REQUIRED>

<!--
      "field"元素定义了须要验证的属性。在一个web应用中,一个字段会对应
      一个在HTML表单中的空间。为了验证这些属性,验证器以JavaBean的方式
      工做。field元素接受以下
      属性:
      property         对应于此field元素的JavaBean(一般为ActionForm)中须要验证的属性。
      depends          在调用证以前所须要调用的其余验证的列表,多个用逗号分隔。
                      若是想要进行当前验证,那么列表中的全部验证必须成功。
      page             与当前表单相应的JavaBean(一般为ActionForm)可能包含一个
                      page属性。只有字段中的"page"属性值等于或者小于表单中的
                      值时框架才会处理JavaBean。若是是使用带有"wizard"(向导)
                      来完成一个大型表单的话,这个属性会很是有用,由于它能够
                      防止某些页面被无心中跳过。
       [0]——默认值。
      indexedListProperty
                      "indexedListProperty"便可以返回一个数组或者Collection类
                      方法名。能够经过此方法获得一个列表而后经过这个列表的循环访问
                      ,执行对字段的验证。
-->
<!ELEMENT field (msg|arg|arg0|arg1|arg2|arg3|var)*>
<!ATTLIST field property CDATA #REQUIRED>
<!ATTLIST field depends CDATA #IMPLIED>
<!ATTLIST field page CDATA #IMPLIED>
<!ATTLIST field indexedListProperty CDATA #IMPLIED>

<!--
      "msg"元素定义了一个自定义消息key,当验证字段失败时,使用此消息key。
      当当前的字段验证失败且msg元素没有指定值时,每一个验证器都会使用自身
      默认的消息属性。应用到字段的每一个验证器能够有本身的msg元素。
      msg元素接受以下的属性
       name         指定对应此msg元素的验证器(验证规则)的名称。
     
       bundle       指明包含key属性所指名称的消息资源绑定。
       key          消息资源绑定中返回消息模版的key。
       resource     若是设置为"false", 表示直接在key属性中设置文本。若是为
             "true"则使用消息资源绑定中的值。
                   [true]——默认值。
-->
<!ELEMENT msg EMPTY>
<!ATTLIST msg key CDATA #REQUIRED>
<!ATTLIST msg name CDATA #REQUIRED>
<!ATTLIST msg bundle CDATA #IMPLIED>
<!ATTLIST msg resource CDATA #IMPLIED>
 
<!--
      "arg"元素为使用它的验证器或者field定义了消息替换模版。
      arg元素接受以下属性。
       name         与msg元素对应的验证器的名称。
             若是没有指定这个属性,则适用于全部的验证规则,
             并取代position中指定的位置的参数。
           
       bundle       指明包含key属性所指名称的消息资源绑定。
       key          消息资源绑定中返回消息模版的key。
       resource     若是设置为"false", 表示直接在key属性中设置文本。若是为
             "true"则使用消息资源绑定中的值。
                   [true]——默认值。
                 
       position     在消息中替换参数的未知。
             例如,position="0"就是第一个参数。
             [0]——默认值
-->
<!ELEMENT arg EMPTY>
<!ATTLIST arg key CDATA #REQUIRED>
<!ATTLIST arg bundle CDATA #IMPLIED>
<!ATTLIST arg name CDATA #IMPLIED>
<!ATTLIST arg resource CDATA #IMPLIED>
<!ATTLIST arg position CDATA #IMPLIED>
 
<!--
  “特别不建议”经过使用<arg position="0"/>来替代arg0元素!
      "arg0"元素为使用它的验证器或者field定义了消息替换模版中的第一个
      替换参数的值。
      arg0元素接受如下属性。
       name         与msg元素对应的验证器的名称。
     
       key          消息资源绑定中返回消息模版的key。
       resource     若是设置为"false", 表示直接在key属性中设置文本。若是为
             "true"则使用消息资源绑定中的值。
                   [true]——默认值。
-->
<!ELEMENT arg0 EMPTY>
<!ATTLIST arg0 name CDATA #IMPLIED>
<!ATTLIST arg0 key CDATA #IMPLIED>
<!ATTLIST arg0 resource CDATA #IMPLIED>

<!--
  “特别不建议”经过使用<arg position="1"/>来替代arg1元素!
      "arg1"元素为使用它的验证器或者field定义了消息替换模版中的第二个
      替换参数的值。
      arg1元素接受如下属性。
       name         与msg元素对应的验证器的名称。
     
       key          消息资源绑定中返回消息模版的key。
       resource     若是设置为"false", 表示直接在key属性中设置文本。若是为
             "true"则使用消息资源绑定中的值。
                   [true]——默认值。
-->
<!ELEMENT arg1 EMPTY>
<!ATTLIST arg1 name CDATA #IMPLIED>
<!ATTLIST arg1 key CDATA #IMPLIED>
<!ATTLIST arg1 resource CDATA #IMPLIED>

<!--
  “特别不建议”经过使用<arg position="2"/>来替代arg2元素!
      "arg2"元素为使用它的验证器或者field定义了消息替换模版中的第三个
      替换参数的值。
      arg2元素接受如下属性。
       name         与msg元素对应的验证器的名称。
     
       key          消息资源绑定中返回消息模版的key。
       resource     若是设置为"false", 表示直接在key属性中设置文本。若是为
             "true"则使用消息资源绑定中的值。
                   [true]——默认值。
-->
<!ELEMENT arg2 EMPTY>
<!ATTLIST arg2 name CDATA #IMPLIED>
<!ATTLIST arg2 key CDATA #IMPLIED>
<!ATTLIST arg2 resource CDATA #IMPLIED>

<!--
  “特别不建议”经过使用<arg position="3"/>来替代arg3元素!
      "arg3"元素为使用它的验证器或者field定义了消息替换模版中的第四个
      替换参数的值。
      arg3元素接受如下属性。
       name         与msg元素对应的验证器的名称。
     
       key          消息资源绑定中返回消息模版的key。
       resource     若是设置为"false", 表示直接在key属性中设置文本。若是为
             "true"则使用消息资源绑定中的值。
                   [true]——默认值。
-->
<!ELEMENT arg3 EMPTY>
<!ATTLIST arg3 name CDATA #IMPLIED>
<!ATTLIST arg3 key CDATA #IMPLIED>
<!ATTLIST arg3 resource CDATA #IMPLIED>

<!--
      "var"元素设置一个参数,使得field元素把它传递给相应的验证器,
      例如,在一个最小或者最大值的范围验证中的值。这些参数一样也可
      被一个arg?所引用,可是必须经过使用shell语法:${var:var-name}
      才行。
-->
<!ELEMENT var (var-name, var-value, var-jstype?)>
 
<!--
      须要提交给字段验证器的变量的名称。
-->
<!ELEMENT var-name   (#PCDATA)>
 
<!--
      须要提交给字段验证器的变量的值。
-->
<!ELEMENT var-value (#PCDATA)>
<!--
      JavaScript类型,可选值 [int| string | regexp]
-->
<!ELEMENT var-jstype (#PCDATA)>

 

 

【第6步】ErrorDescription.properties文件中添加错误信息

   
打开ErrorDescription.properties文件,在文件的后面添加以下的内容:

  error.name.blank = 姓名不能为空
  error.name.minLength = 
姓名的长度不能小于{0}
  error.name.maxLength = 
姓名的长度不能大于{0}
  error.name.alphanum = 
姓名必须由字母和数字组成
  error.age.blank = 
年龄不能为空
  error.age.integer = 
年龄必须为数字
  error.age.intRange = 
年龄必须在{0}{1}之间

  启动Tomcat,在IE中输入以下的URL来测试程序:

   
http://localhost:8080/samples/%20firstValidator.jsp

   
在输入一些错误信息后,点击“提交”按钮,将出现相似下图的效果。

将会按着depends属性中的约束来验证items属性的每个值。咱们还能够将propertyindexedListProperty配合使用,以下面代码所示:

  <field indexedListProperty="items"  property="employee.age"  depends=>  </field>

    Validator框架将根据上述的配置代码来验证items属性中的每一项的employee.age属性。

2、使用常量和变量

1. 常量

   
Struts1.x系列教程(10):Validator验证框架入门》一文中的name属性使用了mask进行验证。这个mask实际上表明了一个正则表达式。但若是在validator.xml文件中有不少个地方须要用到这个正则表达式,那就它就会在不少地方重复。为此,咱们可使用常量来避免这种事情发生。   

常量分为全局常量和局部常量。

1)全局常量

全局常量能够被用在validator.xml中定义的全部form中。咱们可使用<global>元素来配置全局常量。为了配置全局常量,将以下的内容放到第一个<formset>元素的前面。

  <global>
      
<constant>
          
<constant-name>mask</constant-name>
          
<constant-value> ^[a-zA-Z0-9]*$ </constant-value>
      
</constant>
  
</global>
  
<formset>

2)局部常量
   
局部常量须要放到<formset>元素的开始位置(根据DTD的定义,局部常量只能放到这里,而全局常量能够放在第一个<formset>元素的前面,也能够放到<formset>的后面)。以下面的代码所示:

  <formset>
      
<constant>
          
<constant-name>mask</constant-name>
          
<constant-value> ^[a-zA-Z0-9]*$ </constant-value>
      
</constant>
      
<form name="firstValidatorForm"> 
       
  
</formset>

 咱们能够编写以下的代码来使用mask常量:

<var>
    <var-name>mask</var-name>
    <var-value> ${mask}</var-value>
</var>


2. 变量
    Validator
框架经过<var>元素来定义变量。变量将做为<field>的子元素被使用。主要向depends属性值 (如mask)以及<msg>的错误信息传递数据。以下面的代码经过变量required姓名传递给了错误信息的第一个参数{0}

<field property="name"  depends="required ">
    <msg name="required" key="error.name.blank" />
    <arg name="required" key="${var:required}" position="0" resource="false" />
    <var>
        <var-name>required</var-name>
       
<var-value>姓名</var-value>
   
</var>
</field>

3、客户端验证

 使用Validator框架的好处之一就是能够很容易地将服务端验证变为客户端验证(JavaScript验证)。为了完成这一转换,咱们只须要修改两个地方。如今就拿Struts1.x系列教程(10):Validator验证框架入门》中的firstValidator.jsp为例来讲明要修改什么。
   
首先,在firstValidator.jsp中的任何地方(固然,任何地方指的是客户端代码区,并不包括<%...%><%--... --%>所包含的内容)添加以下的<html:javascript>标签:

  <html:javascript formName="firstValidatorForm"/>

而后在<html:form>标签中加入以下的属性:

  onsubmit="return validateFirstValidatorForm(this);"

    如今再运行firstValidator.jsp,若是输入错误,IE就会直接弹出错误信息对话框。咱们查看客户端源代码就会发现,在源代码中多了不少JavaScript代码。实际上,当加入<html:javascript>标签后,在运行JSP页面时,Servlet引擎就会将Validator框架中JavaScript版本的预约义验证代码连同HTML代码都发送到客户端。这些JavaScript代码中有一个入口函数,这个函数的名称前缀为validate,后面是首字母大写的Form名。在<html:form>标签中的onsubmit事件中调用这个入口函数就能够经过JavaScript代码来验证客户端录入的数据了。

下面列出了Validator框架的预约义验证(Struts的版本号为1.2.9)。

Validator

变量

引起条件

required

字段只有空格

validwhen

test

test条件失败(详见下一节)

minlength

minlength

字段的字符数小于minlength

maxlength

maxlength

字段的字符数大于maxlength

mask

mask

字段值不匹配mask所指的个正则表达式

byteshortintegerlongfloatdouble

字段值没法转换为这些数据类型

date

datePattern

datePatternStrict

字值值不能按着指定的格式转换为日期类型

intRangefloatRangedoubleRange

minmax

字段值不在指定的范围内

creditCard

字段值不是一个信誉卡号

email

字段值不是一个合法的email

url

allowallschemes

allow2slashes

nofragments

schemes

字段不是一个URL

关于Validator框架标准验证的详细信息,读者能够访问以下的URL  

http://struts.apache.org/1.2.9/userGuide/dev_validator.html

    下面来举一个validwhen验证的例子。
    validwhen
能够验证当前属性和其余属性的关系,如在验证密码时,要保证两次输入的密码一致,验证代码以下:

<field property="password1" depends="validwhen">
    <msg name="validwhen" key="error.password1.confirmation" />
   
<var>
       
<var-name>test</var-name>
       
<var-value>
            (password1!= null) and (*this* == password)
       
</var-value>
   
</var>
</field>


   
使用validwhen也能够验证嵌套和索引属性,以下面的代码所示:

<field property="field1" depends="validwhen">
    <msg name="validwhen" key="error.field.message" />
   
<var>
       
<var-name>test</var-name>
       
<var-value>
            (*this* == field2.name) and (*this* != field3[1])
       
</var-value>
   
</var>
</field>

    其中*this*表示当前属性的值。

====================================================================

1、动态Form简介

    虽然ActionForm功能强大,但有些时候使用起来有些麻烦。如每创建一个用户录入界面(JSP页面),就得创建一个ActionForm子类来和这个页面对应。固然,咱们能够采用嵌套属性从必定程度上弥补这个问题。可是在创建新的用户录入界面时,仍不可避免地要创建新的ActionForm子类。

    Struts1.2.6及之后的Struts版本中提供了一种动态Form的技术。使得不用再创建新的ActionForm就能够封装用户提交的数据。实际上,这种技术将定义ActionForm子类的工做变成了编写XML文件的工做。

    每定义一个动态Form,就要在struts-config.xml中加一个<form-bean>元素,并使用<form-property>子元素来定义动态Form的属性。

    在本章的最后还会介绍一个LazyValidatorForm类,经过这个类甚至能够不定义动态Form的属性就可使用动态Form。这将大大简化开发人员的工做量。    

2、声明动态Form 

    声明一个动态Form很是简单,只须要在struts- config.xml<form-beans>元素中加入一个<form-bean>子元素,并使用<form- property>元素来定义动态Form的属性。咱们能够定义的属性类型有简单属性(如String)、索引属性(如数组)、映射属性(如 HashMap)以及嵌套属性(属性类型是另外一个类)。
   
对于动态Form来讲,Form的类型必须是org.apache.struts.action.DynaActionForm或其子类。声明一个动态Form的代码以下:

<form-bean name="dynamicForm"  type="org.apache.struts.action.DynaActionForm">
    <!-- 声明一个简单属性 -->
    <form-property name="simpleProp" type="java.lang.String" initial="bill"/>
    <!-- 声明一个索引属性 -->
    <form-property name="indexedProp" type="java.lang.String[]" />
    <!-- 声明一个映射属性 -->
    <form-property name="mappedProp" type="java.util.HashMap" />
    <!-- 声明一个嵌套属性 -->
    <form-property name="nestedProp" type="com.bean.MyBean" />
</form-bean>

3、动态Form的属性类型

    下面列出了动态Form支持的简单属性的全部类型:

  • java.math.BigDecimal
  • java.math.BigInteger
  • java.lang.Boolean
  • java.lang.Byte
  • java.lang.Character
  • java.lang.Class
  • java.lang.Double
  • java.lang.Float
  • java.lang.Integer
  • java.lang.Long
  • java.lang.Short
  • java.lang.String
  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp 

实际上,上面的数据类型就是Java中提供了简单数据类型。它们用在动态Form中和在Java中表明的数据类型是彻底同样的。咱们还可使用<form-property>元素的initial属性为动态Form的简单属性指定一个默认值。如在例程6-11name属性的默认值为“bill”。

对于索引属性的类型来讲,能够是数组,也能够是java.util.List接口的类(如ArrayList)。咱们还能够为动态Form的属性指定实现java.util.Map接口的类做为数据类型(也就是映射属性)。但遗憾的是,若是使用动态Form,就没法使用泛型进行自动类型转换了。

4、访问动态Form

    咱们可使用DynaActionForm类的getter方法来读取动态Form中的属性值。DynaActionForm类的getter方法有三个重载形式,分别用来读取简单属性、索引属性和映射属性。这三个getter方法的定义以下:

  public Object get(String name) ;   // 读取简单属性
  public Object get(String name, int index) ;  // 读取索引属性
  public Object get(String name, String key);  // 读取映射属性

   
   
下面的代码演示了如何经过getter方法得到动态Form的属性值:

DynaActionForm dForm = (DynaActionForm)form;
String name = (String)dForm.get("name");
String[] hobbies = (String[])dForm.get(“hobbies”);
String value1 = (String)dForm.get(“myMap”, “key1”);

    除了上述的get方法外,DynaActionForm还提供了getStringgetString方法,分别用来读取StringString[]类型的属性值,这两个方法的定义以下:

public String getString(String name) ;  
public String[] getStrings(String name) ;

    下面的代码演示了如何经过getStringgetStrings方法得到动态Form的属性值:

String name = dForm.getString(“name”);  // 至关于String name = (String)dForm.get("name");
String[] hobbies = dForm.getStrings(“hobbies”);  // 至关于String[] hobbies = (String[])dForm.get(“hobbies”);

    在使用getStringgetStrings方法时应注意,这两个方法只能读取StringString[]类型的属性,读取其余类型的属性将会抛出异常。  

5、一个动态Form的例子

    咱们在这一部分来实现一个完整的动态Form的例子,在这个例子中的动态Form有四个属性,三个是简单数据类型,一个是数组类型。完成这个例子须要以下四步:

【第1步】配置动态Form
   
打开struts-config.xml,在<form-beans>元素中加入以下的内容:

<form-bean name="dynamicForm" type="org.apache.struts.action.DynaActionForm">
    <form-property name="name" type="java.lang.String" />
    <form-property name="age" type="java.lang.Short" />
    <form-property name="salary" type="java.lang.Float" />
    <form-property name="hobby" type="java.lang.String[]" />
</form-bean>

【第2步】编写Struts Action
   
这个Struts Action类负责从动态Form中得到属性值,并输出到客户端浏览器。在<samples工程目录>"src"action目录中创建一个DynamicAction.java文件,代码以下:

  package chapter6.action;
  
  
import javax.servlet.http.*;
  
import org.apache.struts.action.*;
  
import java.io.*;
  
  
public class DynamicAction extends Action
  {
      
public ActionForward execute(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      {
          
try
          {
              DynaActionForm dForm = (DynaActionForm) form;
              String name = (String) dForm.get("name");
              Short age = (Short) dForm.get("age");
              Float salary = (Float) dForm.get("salary");
              
// 得到数组类型字段值的数组长度
              int hobbyCount = ((String[]) dForm.get("hobby")).length;
              PrintWriter out = response.getWriter();
              out.println("name: " + name + "<p/>");
              out.println("age: " + age + "<p/>");
              out.println("salary: " + salary + "<p/>");
              
for (int i = 0; i < hobbyCount; i++)
                  out.println("hobby" + (i + 1) + ": " + dForm.get("hobby", i) + "<p/>");
          }
          
catch (Exception e)
          {
          }
          
return null;
      }
  }

【第3步】配置Struts Action     

    打开struts-config.xml文件,在<action-mappings>元素中加入以下的内容:

  <action name="dynamicForm" path="/dynamic" scope="request" type="action.DynamicAction" />


【第4步】编写用户录入数据的JSP页面

    Web根目录中创建一个dynamic.jsp文件,代码以下:

  <%@ page pageEncoding="GBK"%>
  <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
  
<html>
    
<head>
      
<title>测试动态Form</title>
      
<html:base/>
    
</head>
    
<body> 
      
<html:form action="dynamic"  >
         
  名:<html:text property="name" />&nbsp;&nbsp;<p>
         
  龄:<html:text property="age" />&nbsp;&nbsp;<p>
         
  资:<html:text property="salary" />&nbsp;&nbsp;<p>
         
爱好1<html:text property="hobby"  value=""/>&nbsp;&nbsp;<p>
         
爱好2<html:text property="hobby" value=""/>&nbsp;&nbsp;<p>
         
爱好3<html:text property="hobby" value=""/>&nbsp;&nbsp;<p>
                
<html:submit value="提交" />
      
</html:form>  
    
</body> 
  
</html>


   
启动Tomcat后,在IE中输入以下的URL来测试程序:

http://localhost:8080/samples/dynamic.jsp

6、验证动态Form

有两种方法能够验证动态Form

1. DynaActionForm的子类中覆盖validate方法。

2. 若是要使用Validator框架来验证动态Form,须要用DynaActionForm的子类org.apache.struts.validator. DynaValidatorForm或其子类来做为动态Form的类型。

在使用DynaValidatorForm的了类时,要想使用Validator框架的验证机制,须要在DynaValidatorForm子类的validate方法的开始位置使用 super.validate()语句来调用DynaValidatorForm中的validate方法

相关文章
相关标签/搜索