WebWork教程三

验证框架

  WebWork提供了在Action执行之前,对输入数据的验证功能,它使用了其核心XWork的验证框架。提供了如下功能:

  1、 可配置的验证文件。它的验证文件是一个独立的XML配置文件,对验证的添加、修改只需更改配置文件,无需编译任何的Class。

  2、 验证文件和被验证的对象完全解藕。验证对象是普通的JavaBean就可以了(可以是FormBean、域对象等),它们不需实现任何额外的方法或继承额外的类。

  3、 多种不同的验证方式。因为它验证功能是可以继承的,所以可以用多种不同的方式指定验证文件,比如:通过父类的Action、通过Action、通过Action的方法、通过Action所使用的对象,等等。

  4、 强大的表达式验证。它使用了OGNL的表达式语言,提供强大的表达式验证功能。

  5、 同时支持服务器端和客户端验证。

  为用户注册添加验证功能

  下面我们来看看如何为用户注册添加验证功能:

  1、 注册我们的验证类型

  WebWork为不同的验证要求提供不同的验证类型。一个验证类型,一般是有一个类来提供。这个类必须实现接口:com.opensymphony.xwork.validator.Validator,但我们在写自己的验证类型时,无需直接实现Validator接口,它有抽象类可供直接使用如ValidatorSupport、FieldValidatorSupport等。

  验证类型在使用之前,必须要在ValidatorFactory(com.opensymphony.xwork.validator. ValidatorFactory)中注册。可以有二种方法实现验证类型的注册。一、写程序代码进行注册,它使用ValidatorFactory类的静态方法:registerValidator(String name, String className)。二、使用配置文件validators.xml进行注册,要求把文件validators.xml放到ClassPath的跟目录中(/WEB-INF/classes)。但在实际开发中,一般都使用第二中注册方法。我们的验证类型注册如下:

代码
<validators></validators>
<validator class="com.opensymphony.xwork.validator.validators.RequiredFieldValidator" name="required"></validator>
<validator class="com.opensymphony.xwork.validator.validators.RequiredStringValidator" name="requiredstring"></validator>
<validator class="com.opensymphony.xwork.validator.validators.IntRangeFieldValidator" name="int"></validator>
<validator class="com.opensymphony.xwork.validator.validators.DateRangeFieldValidator" name="date"></validator>
<validator class="com.opensymphony.xwork.validator.validators.ExpressionValidator" name="expression"></validator>
<validator class="com.opensymphony.xwork.validator.validators.FieldExpressionValidator" name="fieldexpression"></validator>
<validator class="com.opensymphony.xwork.validator.validators.EmailValidator" name="email"></validator>
<validator class="com.opensymphony.xwork.validator.validators.URLValidator" name="url"></validator>
<validator class="com.opensymphony.xwork.validator.validators.VisitorFieldValidator" name="visitor"></validator>
<validator class="com.opensymphony.xwork.validator.validators.ConversionErrorFieldValidator" name="conversion"></validator>
<validator class="com.opensymphony.xwork.validator.validators.StringLengthFieldValidator" name="stringlength"></validator>


  注册验证类型的配置文件非常简单。它使用标签<validator></validator>提供名-值对的形式注册。这样我们的验证文件就可以直接引用它的名字。

  2、 开启Action的验证功能

  如果Action要使用验证框架的验证功能,它必须在配置文件中指定拦截器“validation”,它的定义如下:

代码
<interceptor class="com.opensymphony.xwork.validator.ValidationInterceptor" name="validation"></interceptor>


  我们的验证文件必须以ActionName-validation.xml格式命名,它必须被放置到与这个Action相同的包中。你也可以为这个Action通过别名的方式指定验证文件,它的命名格式为:ActionName-aliasname-validation.xml。“ActionName ”是我们Action的类名;“aliasname”是我们在配置文件(xwork.xml)中定义这个Action所用到的名称。这样,同一个Action类,在配置文件中的不同定义就可以对应不同的验证文件。验证框架也会根据Action的继承结构去查找Action的父类验证文件,如果找到它会去执行这个父类的验证。

  3、 实现我们的验证文件:RegisterActionSupport-validation.xml

代码

<validators></validators>
       <field name="user.username"></field>
        <field-validator type="requiredstring"></field-validator>
               <message></message>You must enter a value for username.
          
      
       <field name="user.password"></field>
        <field-validator type="requiredstring"></field-validator>
               <message></message>You must enter a value for password.
          
           <field-validator type="fieldexpression"></field-validator>
               user.password == verifyPassword
               <message></message>Passwords don't match.
          
      
       <field name="user.email"></field>
        <field-validator type="email"></field-validator>
               <message></message>You must enter a valid email.
          
      
       <field name="user.age"></field>
        <field-validator type="int"></field-validator>
               6
               100
               <message></message>Age must be between ${min} and ${max}, current value is ${user.age}.
          
      


  说明:

  1)、<field></field>标签代表一个字段,它的属性“name”和页面输入框的“name”属性必需完全一致,其实它也就是我们的表达式语言。

  2)、<field-validator></field-validator>标签定义我们的验证规则,type属性的值就是就是我们前面定义的验证类型。

  3)、验证文件中,字段的数据是通过表达式语言从我们的值堆栈(OgnlValueStack)中取得,一般是Action或Model对象。例如:我们的字段“user.age”,它会通过Action的getUser().getAge()来取得用户输入的年龄,再来根据验证的类型“int”和最大值最小值的参数来判断输入的数据是否能通过验证。

  4)、不管验证是否通过,我们的Action都会执行,但如果验证没有通过,它不会调用Action的execute()方法。

  4、 显示Action的验证错误信息

  如果用户输入的数据验证没有通过,我们需重新返回输入页面,并给出错误信息提示。拦截器栈“validationWorkflowStack”为我们实现了这个功能。它首先验证用户输入的数据,如果验证没有通过将不执行我们Action的execute()方法,而是将请求重新返回到输入页面。

  我们的xwork.xml配置文件如下:

代码
<action class="example.register.RegisterActionSupport" name="registerSupport"></action>
<result name="success" type="dispatcher"></result>
/register-result.jsp

<result name="input" type="dispatcher"></result>
/registerSupport.jsp

<interceptor-ref name="validationWorkflowStack"></interceptor-ref>


  通过接口ValidationAware,我们可以获得类级别或字段级别的验证错误信息,这个错误信息也就是我们验证文件中<message></message>标签里的数据。ActionSupport类已实现了此接口,这样在应用中我们的Action只要继承ActionSupport类就可以了。RegisterActionSupport.java代码如下:

代码
package example.register;

import com.opensymphony.xwork.ActionSupport;

/**
* @author moxie-qac
*             achqian@yahoo.com.cn
*
*/
public class RegisterActionSupport extends ActionSupport {

private User user= new User();
private String verifyPassword;

public User getUser(){
return this.user;
}

public String execute(){
//在这里调用用户注册的业务逻辑,比如:将注册信息存储到数据库
return SUCCESS;
}

public String getVerifyPassword(){
return this.verifyPassword;
}

public void setVerifyPassword(String verPassword){
this.verifyPassword = verPassword;
}
}


  我们WebWork的UI标签库直接提供了验证错误信息显示功能。如果字段级别的验证没有通过,它会在输入框上方显示验证文件定义的错误提示信息。我们将用户输入的页面更改如下:

registerSupport.jsp

代码





<ww:form name="'test'" method="'POST'" action="'/example/registerSupport.action'">
<ww:textfield name="'user.username'" required="true" label="'Username'"></ww:textfield>
<ww:textfield name="'user.password'" required="true" label="'Password'"></ww:textfield>
<ww:textfield name="'verifyPassword'" required="true" label="'VerifyPassword'"></ww:textfield>
<ww:textfield name="'user.email'" required="true" label="'Email'"></ww:textfield>
<ww:textfield name="'user.age'" required="true" label="'Age'"></ww:textfield>
<ww:submit value="'Submit'"></ww:submit>
</ww:form>




  我们上面的例子使用的是服务器端验证。WebWork也为我们提供了方便的客户端验证。它将验证自动生成JavaScript脚本。如果要使用客户端验证只需改变相应的验证类型就可以了(输入页面的表单必需使用<ww:form>标签,并设置属性“validate="true"”)。具体的验证类型可以在WebWork的包com.opensymphony.webwork.validators中找到。</ww:form>
XWork配置详述

  XWork配置文件是以“xwork”命名的.xml文件,它必需放到类路径(classPath)的根目录, Web应用一般放在classes目录中,它需要遵守DTD的规范(现在是xwork-1.0.dtd)。这个文件定义了我们的Action,Interceptor,Result的配置和相互之间的映射。下面我们看看用户注册的完整XWork配置文件:

代码


<xwork></xwork>

<include file="webwork-default.xml"></include>

<package name="example" extends="webwork-default"></package>
<action class="example.register.RegisterAction" name="register"></action>
     <result name="success" type="dispatcher"></result>
      /register-result.jsp
    
     <interceptor-ref name="params"></interceptor-ref>


<action class="example.register.RegisterActionSupport" name="registersupport"></action>
     <result name="success" type="dispatcher"></result>
      /register-result.jsp
    
     <result name="input" type="dispatcher"></result>
      /registerSupport.jsp
    
     <interceptor-ref name="validationWorkflowStack"></interceptor-ref>


     



xwork.xml文件的标签元素

  Xwork:xwork配置文件的所有内容,都是定义在<xwork></xwork>标签中,它的直接子标签有 <package></package> 和<include></include>。

  Package:我们的Action,Interceptor,Result都是在此标签中定义。 <package></package> 标签有一个必需的属性“name”,它用来标识唯一的一个package。属性“extends”是可选的,它用来继承前面定义的一个或一个以上package配置信息,包括所有的interceptor、interceptor-stack和action的配置信息。注意,配置文件按文档的顺序,由上向下执行,因此,用“extends”引用的package必需在引用之前定义。属性“sbstract”是可选的,它用来设置package为抽象的package,它可以被继承同时它的Action配置信息在运行时将不可见。

  属性namespace也是可选的,它用来分隔不同package定义的action,让这些action处于不同的命名空间(namespaces)。这样,我们不同的package可以有相同的action命名,因为可以通过命名空间来区分。如果不指定namespace,默认的是空字符串。命名空间也可以被用在安全控制方面,它可以根据不同的命名空间指定不同的访问权限。

  属性
是否必需描述
name

用来标识package的名称
extends

继承它所扩展的package配置信息
namespace

指定package的命名空间,默认是””
abstract

声明package是抽象的


  Result-type:用来定义输出结果类型的Class,它用简单的名-值对来定义。当然,我们自己写的输出结果类型也必需在这里定义。例如:

<result-type class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult" name="dispatcher" default="true"></result-type>,default="true"表示如果在Action的result中不指定result-type,就使用这个默认的result-type。

  Interceptors:它是一个简单的<interceptors></interceptors> <interceptors></interceptors>标签,我们的interceptor和interceptor-stack都在此标签内定义。

  Interceptor:当然,就是用来定义我们的拦截器。它的定义非常简单,名-值对的形式。例如:<interceptor class="com.opensymphony.xwork.interceptor.TimerInterceptor" name="timer"></interceptor>。在action中,可以通过<interceptor-ref></interceptor-ref>来直接引用前面定义了的拦截器。

  Interceptor-stack:用来将上面定义的interceptor组织成堆栈的形式,这样我们就可以创建一组标准的interceptor,让它按照顺序执行。在我们的Action中直接引用这个interceptor堆栈就可以了,不用逐个interceptor去引用。

  例如:

代码
<interceptor-stack name="validationWorkflowStack"></interceptor-stack>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="validation"></interceptor-ref>
<interceptor-ref name="workflow"></interceptor-ref>


  Interceptor Param:我们的interceptor是在ActionConfig级别被实例化和存储的,也就是说一个Action引用的每个interceptor都会有相应的实例。这样,我们在定义和引用interceptor的时候都可以为它设置相应的参数值。例如:

代码
<interceptor class="com.opensymphony.xwork.TestInterceptor" name="test"></interceptor>
expectedFoo


  在Action或Interceptor-stack中引用时也可以设置参数,例如:

代码
<interceptor-ref name="test"></interceptor-ref>
expectedFoo


  注意:在Action引用的时候,如果引用的是Interceptor-stack,则不允许设置参数,否则会报错。

  Global-results:它允许我们定义全局的输出结果(global result),比如登陆页面、操作错误处理页面。只要继承它所在的package,这些输出结果都是可见的。

  例如:

代码
<global-results></global-results>
<result name="login" type="dispatcher"></result>
     /login.jsp

<result name="error" type="dispatcher"></result>
     /error.jsp



  如果我们的Action执行完返回“login”,它将调用上面的这个输出结果,将输出派遣到根目录下的login.jsp页面。

  Action:用来配置Action的名称(name)和它对应的Class。我们将通过这个Action的名称和它所在package的namespace去配置文件中取得这个Action的配置信息。它可以通过 来设置参数,Action在执行的时候会取得配置文件里设置的参数(通过拦截器StaticParametersInterceptor)。

  Action可以配置一个或多个输出结果(result)。一个输出结果的名称,对应于Action执行完成返回的字符串。<result></result>标签的type属性,对应我们前面定义过的result-type,说明reslut的类型。例如:

代码
<action class="example.register.RegisterAction" name="register"></action>
<result name="success" type="dispatcher"></result>
     /register-result.jsp

<interceptor-ref name="params"></interceptor-ref>


  当然,我们的Action用到的拦截器也是在这里配置的,通过<interceptor-ref></interceptor-ref>标签,属性“name”的值,对应前面定义的interceptor或interceptor-stack。如果Action中没有用<interceptor-ref></interceptor-ref>标签指定拦截器,它将使用默认的<default-interceptor-ref></default-interceptor-ref>标签定义的拦截器。

  Include:xwork..xml文件可以被分成好几个不同的文件,xwork..xml通过<include></include>标签引用被包含的文件,例如:<include file="webwork-default.xml"></include>。被包含的文件必需是package标签里的内容,我们看看<include></include>标签在配置文件里的位置就知道了。如果要继承被包含文件的package,我们必需将<include></include>标签放在其上面,因为配置文件是按照由上而下的顺序解析的。

实战G-Roller-WW

G-Roller-WW介绍

JSTL与WebWork的整合

中文解决方案


WebWork与其它开源项目的集成

Spring

Hibernate

Xml-RPC


总结

  WebWork功能非常强大,除了上面介绍的以外,它还有很好的国际化支持功能,IoC(Inversion of control,依赖倒装控制)框架支持;同时,它也可以很好的与其它的开源项目集成,如:Sitemesh、Spring、Pico、Hibernate、JUnit、Quartz等。

  “最好的文档就是代码”,WebWork代码可读性非常好,特别是2.1版本加了很多详尽的注释,在此向读者强烈推荐,如果想更深入了解WebWork,建议多看它的代码文档。

  到此,您已经了解了WebWork的所有特性。它确实是一个非常优秀的开源J2EE Web框架,同时我并不否定其它的框架,比如Struts,Tapestry,Maverick等,既然存在,它就一定有着自身存在价值和理由。

  这么多的Web框架,有很多朋友在面临选择的时候也许会非常矛盾,不知应该如何抉择。在这,我的建议:关于开源Web框架的选择,应该根据团队的整体技术能力和要实施的项目来共同决定。关于是否要在项目中使用WebWork,假如你们已经在团队中使用类似Struts这样的J2EE框架,开发人员都已熟悉并有了很多技术和项目经验的积累,那我建议你们暂时不要去使用WebWork,但我强烈建议找一个有代表性的模块,将他们尝试用WebWork改写,我想,下个项目,也许你们就会改变注意,考虑使用WebWork。但,如果你们正在为具体选择哪种Web框架而发愁,我相信WebWork一定是您最佳的选择。

  WebWork功能很多,但我们要牢记它的宗旨:致力于组件化和代码重用,同时简单、灵活,更好的提高生产率。

 

 

资料参考自http://www.cnblogs.com/HuaiHuai/archive/2005/08/18/217875.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值