Struts中使用Validator框架

 Struts中使用Validator框架 

每個應用程序都有責任確保它們插入到後臺資料庫的數據是合法有效的,畢竟,如果這些應用程序所依賴的數據一旦遭到了破壞,那將是災難性的,那應用程序還能拿什麼來使自己正常運轉呢?比如說,使用正規關係數據庫的一個應用程序,數據庫中的每個字段都有自己一定的規則和約束,來保證存儲在其中的數據在一定程度上的正確性。任何要使用後臺資料庫數據的應用程序都有責任保護它們提交的數據的完整性。
任何試圖插入或更新不符合標準的數據的操作都有可能被發現並拒絕。這種檢測可能遍佈在整個應用程序的每個角落,在表現層可能進行一些驗證,在業務邏輯層,商業邏輯對象一般也有商業邏輯的驗證,還有在後臺資料庫也要對數據進行檢查。
不幸的是,由於這種驗證在應用程序中無處不在,造成了應用程序在一定程度上的驗證數據的代碼冗餘。這並不是應用程序所希望的,因爲這種在多處的重複勞動,使得應用程序的部署和維護要花去更多的時間。如果在整個應用程序中,這些驗證規則可以重複使用,將使得應用程序更加富有彈性,換句話說就是,部署更快捷,定製更容易,程序更靈活。
Jakarta Commons 項目Validator框架簡介
Validator是由David Winterfeldt創建的開源項目,它也是Jakarta Commons的一個子項目。Commons項目主要是提供一些像Validator這樣的一些可重用組件。其他著名的Commons組件還有如BeanUtils,Digester,Logging框架等。Validator 1.0版本發佈於200211月初。
使用Validator的好處
.使用Validator框架比一般的在應用程序的代碼中定義驗證規則有好多優點,如:
.
可以在一處爲應用程序定義驗證規則;
.
驗證規則和應用程序是鬆耦合的;
.
服務器端和客戶端的驗證規則可以在同一處定義;
.
配置新驗證規則或修改已有驗證規則變得更加簡單;
.
支持國際化;
.
支持正則表達式;
.
可以用於Web應用程序也可用於標準的Java應用程序;
.
採用聲明的方法實現而不是編程實現;
除了之外,Validator最大的特徵就是自身支持可插性(pluggability)。在文章的後面你將會看到使用Validator框架內置的驗證規則來更好地完成你的工作,而更重要的是,Validator框架允許你自定義驗證程序,並插入到框架中。
StrutsValidator的關係
應該指出的是Validator框架本身是因Struts框架而建立的。Validator的創建者David Winterfeldt在使用Struts的過程中發現,在許多ActionForm類中需要反覆使用同一個驗證規則,這樣造成了大量的代碼冗餘。於是他決定創建Validator框架來消除這種冗餘,這樣Validator就誕生了。
儘管Validator架構最初是爲Struts架構而生,但它還是被設計和構造成了可以獨立於Struts架構而單獨使用。這一個特徵使得你可以在任何的應用程序中使用這個框架,不必管它是不是Struts架構的。並不會因爲你不使用Struts框架而影響Validator架構對你的應用程序作用。事實上,這就是爲什麼ValidatorJakarta Commons項目的一部分而不直接是Struts項目的一部分。
現在,我們來將這個框架整合應用到像基於Struts構架這樣的Web應用程序上。在文章的最後中我們再介紹如何把它應用到其他類型的應用程序中,如基於EJB的應用程序。
Validator組件概述
Validator架構有下面這些組件組成:
Validators

配置文件;
資源綁定;
JSP
自定義標籤;
Validator Form
類;
什麼是Validators?
一個Validator就是,執行一個驗證規則時Validator框架調用的一個Java類。框架根據配置文件中定義的方法簽名來調用這個Validaotor類。一般情況下,每個Validator類提供一個單獨的驗證規則,然後這些規則可以組合成更復雜的規則集。
注意:有時出於方便,一個Validator類也可以定義多個驗證規則,而每個規則是一個靜態方法且並不包含任何客戶端狀態信息。
框架提供了14種默認的驗證規則,有時候這些規則也被稱爲Validator框架的基本規則,這些基本規則如表一:
名稱描述
byte,short,integer,long,float,double
檢驗值是否能被轉換成對應的基本數據類型
creditCard
檢驗輸入域是否是一個合法的信用卡號碼
date
檢驗輸入域是否是一個合法日期
email
檢驗輸入是否是一個合法Email地址
mask
檢驗輸入域是否能成功匹配一個正則表達式
maxLength
檢驗值的長度是否小於等於給定的最大長度
minLength
檢驗值的長度是否大於等於給定的最小長度
range
檢驗值的範圍是否在最大值和最小值之間
required
檢驗輸入域是否爲不爲空,或不包含空格值的長度是否大於零

正像你在表一中看到的,Validator框架提供了Web應用程序需要的大多數的驗證規則。你可以使用這些現有的驗證規則來創建自己驗證配置文件。儘管這樣,也正如我們前面提到的,和後面要講到的,你可以根據你的需要隨意的增加更多的Validator
現在,讓我們來討論如何在一個基於Struts架構的應用程序中配置使用這些基本的Validator
使Validator框架具有彈性的原因在於所有的驗證規則和其具體細節都是通過在外部文件中配置聲明實現的。你的應用程序並不必要知道這些具體的驗證規則。這一特徵使得規則集的發生擴展和修改時,你並不用去動你應用程序的源代碼。這一點對你要進行每次的個性化安裝或當需求發生變化時來說是非常重要的。
如果你使用Struts1.1Validator框架,你會用到這樣兩個配置文件,一個叫validator- rules.xml,另一個叫validation.xml;其實你也可以隨意的給他們命名,甚至可以把它們合併成一個XML文件。但是,你還是最好把它們分開,因爲它們各有各的用途。
注意:如果你從Jakarta網站上下載Validator,並不包含這兩個文件。只有在包含的Validator框架的Struts的下載中纔可以找到這兩個文件。
validator-rules.xml文件
validator-rules.xml文件定義應用程序可以使用的Validatorvalidator-rules.xml充當模板的作用,定義所有應用程序可能要用到的Validator
注意:這個xml文件和我們下面要討論的另一個xml文件都應該放到類加載器可以找得到的地方。當我們在Web應用程序中使用Validator框架時,正確的位置應該是在WEB-INF下。
validator-rules.xml文件服從validator- rules_1_1.dtd的管理,validator- rules_1_1.dtd可以在jakarta.apache.org/struts/dtds/validator- rules_1_1.dtd下載到。我們並不想花太多的時間放在研究這個文件的具體細節上,我們在這兒只作一些基本的介紹。
validator-rules.xml文件中最重要的元素包含在元素中,例如,例一:
例一:一個簡單的validator-rules.xml文件
<form-validation>
<global>
<validator
name="required"
classname="org.apache.struts.util.StrutsValidator"
method="validateRequired"
methodparams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest"
msg="errors.required"/>
<validator name="minlength"
classname="org.apache.struts.util.StrutsValidator"
method="validateMinLength"
methodparams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest"
depends="required"
msg="errors.minlength"/>
</global>
</form-validation>
應用程序使用的每個Validator對應一個元素。在例一中給大家展示了兩個Validator,一個是請求Validator,另一個是最小長度Validator。元素支持許多屬性。這些屬性是必要的,用於告知框架這個Validator應當調用哪個正確的類和方法。例如,例一中的請求Validator元素表明這個Validator將調用org.apache.struts.util.StrutsValidator類的validateRequest()方法。Validator也可能要依賴另一個Validator,如例一中的最小長度的Validator就是這樣一個例子,它包含一個depends屬性,用它來表示這個Validator將依賴於請求Validatormsg屬性用一個鍵值指定一個資源綁定,框架將用它來生成正確的錯誤信息。資源綁定的使用有益於錯誤信息的本地化。
元素還支持子元素,允許你指定一個客戶端運行的javascript函數。這樣服務器端和客戶端驗證可以在同一處指定,這使應用程序的維護變得簡單。
validation.xml文件
Validator框架的第二個配置文件就是這個叫validation.xml的文件。其實你可以隨意把它命名爲你喜歡的任何名字,也可以把它放到validator-rules.xml文件中。
validation.xml用於把你在validator-rules.xml中定義的各個Validator和你的應用程序中的組件映射起來。由於我們在這裏討論的是在Struts中使用Validator框架,那麼在這裏validation.xml就是把這些ValidatorStrutsActionForm類建立映射。ActionForm類其實是一個類似JavaBean一樣的類,在Struts中用於捕捉用戶輸入並幫助傳輸這些輸入到下一級應用程序組件。ActionForm也提供了在用戶輸入被傳到業務邏輯層之前驗證這些輸入的便利場所。例二是一個簡單的validation.xml:
例二:一個簡單的validation.xml文件
<form-validation>
<formset>
<form name="checkoutForm">
<field
property="firstName"
depends="required">
<arg0 key="label.firstName"/>
</field>
<field
property="lastName"
depends="required">
<arg0 key="label.lastName"/>
</field>
</form>
</formset>
</form-validation>
例二向大家展現了一個name屬性叫checkoutForm的一個form元素。checkoutForm是一個在Struts配置文件中定義的一個ActionForm Bean。所以,例二的XML文件就是把這個ActionForm Bean和請求Validator建立映射,BeanfirstNamelastName屬性分別對應XML文件中相應的firstNamelastName field元素。
其實它還有許多其它作用,如可以在validation.xml中定義常量和全局變量,用於在整個文件中使用,當你想使時可以方便的反覆使用。對於validation.xml的元素和屬性更詳細的解釋,可以下載jakarta.apache.org/struts/dtds/validation_1_1.dtd參閱。
資源綁定

對於Validator框架,當驗證規則失敗的時候,可以從資源綁定中創建錯誤信息。Validator框架提供幾種默認消息,同一般的應用程序消息資源放在一起。如下:
#Normal resource bundle messages
label.firstName=First Name
label.lastName=Last Name
#Error messages used by the Validator
errors.required={0} is required.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} characters.
errors.invalid={0} is invalid.
...
當一個驗證規則失敗時,這個驗證規則創建一個錯誤信息。框架將自動給消息插入參數。比如說,我們使用例一和例二的驗證規則,當checkoutFormfirstName屬性爲空時,我們會看到這樣的錯誤信息:
First Name is required.
你也可以修改綁定或配置文件來顯示你喜歡的消息。
”ValidatorStruts
現在我們已經瞭解了Validator框架,感覺蠻不錯吧!下面我們將快速的講一下我們是如何輕鬆地在Struts框架中使用Validator框架的。
首先要做的就是讓Struts框架認識Validator框架。你可以使用Struts1.1Plug-in新特性來實現它。只要在Struts配置文件中增加下面代碼即可:
<plug-in classname="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
這樣Struts就可以自動識別Validator框架了。
另外一個必需的步驟就是創建ActionForm Bean(標準的或是動態的)和確保Validator框架的配置文件是可用的,這樣就搞定了。並不需要作一些調用驗證規則或做其他具體的事情,Struts框架會自動完成這些工作,這就是所謂的基於聲明的配置。然後當驗證規則失敗的時候,你就可以用JSP標籤看到顯示的錯誤信息了。
創建自己的Validator
儘管Validator框架已爲大家提供了Web應用程序需要的大多數驗證規則,但有時我們還是需要創建一些自己的驗證規則。幸運的,Validator框架的擴展性相當好,爲你提供了這種便利,而這樣做對程序造成的影響相當小的。
創建自己的Validator並不是一件難事,只要創建一個實現這個規則的Java類即可。比如,(在國外)要去超市買二鍋頭,要驗證顧客是否達到合法飲酒年齡。你可以使用已有的驗證規進行驗證,但我們覺得創建一個驗證規則進行驗證要更加直截了一些。驗證飲酒年齡規則Validator Java代碼如下:
例三:自定義驗證規則
import java.io.Serializable;
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.util.StrutsValidatorUtil;
public class NewValidator implements Serializable{
public static boolean validateDrinkingAge( Object bean,
ValidatorAction va,
Field field,
ActionErrors errors, HttpServletRequest request) {
String value = null;
if (isString(bean)) {
value = (String) bean;
} else {
value =
ValidatorUtil.getvalueAsString(bean, field.getProperty());
}
String sMin = field.getVarvalue("drinkingAge");
if (!GenericValidator.isBlankOrNull(value)) {
try {
int ivalue = Integer.parseInt(value);
int drinkingAge = Integer.parseInt(sMin);
if ( ivalue < drinkingAge ){
errors.add(field.getKey(),
StrutsValidatorUtil.getActionError(request, va, field));
return false;
}
} catch (Exception e) {
errors.add(field.getKey(),
StrutsValidatorUtil.getActionError(request, va, field));
return false;
}
}
return true;
}
private static boolean isString(Object o) {
if (o == null) {
return (true);
}
return (String.class.isInstance(o));
}
}
你創建完新的Validator之後,你只要把他加到現存的Validator框架的validator-rules.xml的列表中,你就可以像使用基本驗證規則一樣使用你自己創建的驗證規則。
在非Struts應用程序中使用Validator框架
正像我們在前面談到的,Validator框架最初是爲在Struts框架中使用而設計的。可是,Validator框架設計的相當靈活,並沒有直接把它耦合在Struts框架中,這樣你就可以在普通的應用程序中也可以使用Validator框架來進行驗證。但是,你必須執行一些必需的步驟。
你可以利用像在Web應用程序中一樣使用配置文件。這也是使用Validatoe框架的另一個優點。你可以在Struts框架使用插件的方式來定位和裝載這些文件。而在非Struts應用程序中你必須人爲地手動的定位和裝載這些配置文件。下面就是應用程序在啓動時一般要調的方法:
...
ValidatorResources resources = new ValidatorResources();
InputStream rules =
ValidateExample.class.getResourceAsStream("validator-rules.xml");
ValidatorResourcesInitializer.initialize(resources, in);
InputStream forms =
ValidateExample.class.getResourceAsStream("validation.xml");
ValidatorResourcesInitializer.initialize(resources, forms);
...
這段代碼片斷創建了一個ValidatorResources實例,並根據兩個配置文件進行了初始化。然後你就可以在你應用程序使用這個ValidatorResources對象驗證你配置的JavaBean了。
例四向你展示如何使用已初始化的ValidatorResources對象來驗證一個Person Bean
例四:如何使用Validator驗證你的Bean
//假設我們已經創建和裝配了一個CheckoutForm Bean對象
CheckoutForm form = new CheckoutForm();
//
使用chekoutForm創建一個Validator
Validator validator = new Validator(resources, "checkoutForm");
//
告訴Validator要驗證哪個Bean
validator.addResource(Validator.BEAN_KEY, form);
//
驗證checkoutForm對象並存儲驗證結果
ValidatorResults results = validator.validate();
在例四中,我們看到我們把checkoutForm JavaBean的名字傳給Validator類的構造器,這是爲了告訴Validator實例使用哪套驗證規則來驗證這個Bean
正如你看到的一樣,在非Struts應用程序中使用Validator框架顯得有點不自動化,但是它還是提供了比較靈活的解決方案。使用Validator框架的另一個好處就是把驗證從源代碼中分離到外部的配置文件中。這使我們可以把更多的時間放在我們的業務邏輯開發上。
客戶端VS服務器端Validator
最後我們簡單的闡述一下Validator框架對javascript的支持。因爲有些應用程序需要執行一些客戶端驗證,在某些時候使用javascript進行一些客戶端的驗證是很有必要的。這裏的客戶端我們一般特指Web瀏覽器。
Validator框架提供使用配置文件中的規則動態和自動生成javascript驗證規則的支持。對於每個元素,它可以有一個子元素和包含一些javascript代碼。當包含一些自定義標籤的JSP頁面被解釋時,javascript也被解釋,並當表單提交時執行這些驗證規則。這些叫javascriptValidatorTag的標籤被包含在Struts的標籤集中。這些標籤可以像這樣進行使用:
筆者認爲在需要時使用一定的javascript是可以接受的。當你需要執行一些客戶端的驗證時,使用Validator框架標籤是也是一種不錯的選擇,而且支持根據用戶的區域進行本地化。
結束語
到此爲止,我給大家簡單地介紹了Validator框架,這些其實是框架的一些表面的東西。這個框架的內容深不可測,僅正則表達式就可以寫一本小冊子。
像任何一個框架一樣,Validator框架爲大家提供的是一個基礎的架構,你可以根據你的需求對其進行擴展和個性化。使用像Validator的框架的最重要的一點就是它們是經過千錘百煉,是技術的精華。你並不需重蹈前人失敗的覆轍,你可以節省下時間把更多的精力集中在對業務邏輯的開發上。
 
資源綁定用於幫助消息本地化和一些其它文本信息的本地化處理。由於它減少了應用程序的許多冗餘的硬編碼,故對應用程序有很大益處。比如,如果你要在JSP頁面中要使用一個“Name”標籤時,你可以把這個字符串放到一個資源綁定中,然後使用資源綁定的一個邏輯鍵值引用這個字符串,而不是直接使用這個字符串,這樣做的好處在於,當你想把這個字符串改爲“First Name”時,你只需在資源綁定中修改一處即可,而不必修改整個應用程序的全部代碼。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章