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
*             [email protected]
*
*/
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章