成長中的記憶
          這是我的成長,這是我的天地,學習JAVA,只因快樂。
          posts - 4,comments - 16,trackbacks - 0
          作者:     Chuck Cavaness
          原文:     http://www.onjava.com/pub/a/onjava/2002/12/11/jakartastruts.html
          譯者:     javaduke
                          Email:javaduke@263.net
                          QQ:658155
                          MSN:javaduke@hotmail.com

                每個應用程序都有責任確保它們插入到后臺資料庫的數據是合法有效的,畢竟,如果這些應用程序所依賴的數據一旦遭到了破壞,那將是災難性的,那應用程序還能拿什么來使自己正常運轉呢?比如說,使用正規關系數據庫的一個應用程序,數據庫中的每個字段都有自己一定的規則和約束,來保證存儲在其中的數據在一定程度上的正確性。任何要使用后臺資料庫數據的應用程序都有責任保護它們提交的數據的完整性。
              任何試圖插入或更新不符合標準的數據的操作都有可能被發現并拒絕。這種檢測可能遍布在整個應用程序的每個角落,在表現層可能進行一些驗證,在業務邏輯層,商業邏輯對象一般也有商業邏輯的驗證,還有在后臺資料庫也要對數據進行檢查。
              不幸的是,由于這種驗證在應用程序中無處不在,造成了應用程序在一定程度上的驗證數據的代碼冗余。這并不是應用程序所希望的,因為這種在多處的重復勞動,使得應用程序的部署和維護要花去更多的時間。如果在整個應用程序中,這些驗證規則可以重復使用,將使得應用程序更加富有彈性,換句話說就是,部署更快捷,定制更容易,程序更靈活。
          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類提供一個單獨的驗證規則,然后這些規則可以組合成更復雜的規則集。

          注意:有時出于方便,一個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.1的Validator框架,你會用到這樣兩個配置文件,一個叫validator- rules.xml,另一個叫validation.xml;其實你也可以隨意的給他們命名,甚至可以把它們合并成一個XML文件。但是,你還是最好把它們分開,因為它們各有各的用途。

          注意:如果你從Jakarta網站上下載Validator,并不包含這兩個文件。只有在包含的Validator框架的Struts的下載中才可以找到這兩個文件。
          validator-rules.xml文件
                  validator-rules.xml文件定義應用程序可以使用的Validator。validator-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>元素中,例如,例一:
          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應當調用哪個正確的類和方法。例如,例一中的請求Validator元素表明這個Validator將調用org.apache.struts.util.StrutsValidator類的validateRequest()方法。Validator也可能要依賴另一個Validator,如例一中的最小長度的Validator就是這樣一個例子,它包含一個depends屬性,用它來表示這個Validator將依賴于請求Validator。msg屬性用一個鍵值指定一個資源綁定,框架將用它來生成正確的錯誤信息。資源綁定的使用有益于錯誤信息的本地化。
              <validator>元素還支持<javascript>子元素,允許你指定一個客戶端運行的JavaScript函數。這樣服務器端和客戶端驗證可以在同一處指定,這使應用程序的維護變得簡單。

          validation.xml文件
                Validator框架的第二個配置文件就是這個叫validation.xml的文件。其實你可以隨意把它命名為你喜歡的任何名字,也可以把它放到validator-rules.xml文件中。
              validation.xml用于把你在validator-rules.xml中定義的各個Validator和你的應用程序中的組件映射起來。由于我們在這里討論的是在Struts中使用Validator框架,那么在這里validation.xml就是把這些Validator和Struts的ActionForm類建立映射。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建立映射,Bean的firstName和lastName屬性分別對應XML文件中相應的firstName和lastName<field>元素。
              其實它還有許多其它作用,如可以在validation.xml中定義常量和全局變量,用于在整個文件中使用,當你想使時可以方便的反復使用。對于validation.xml的元素和屬性更詳細的解釋,可以下載jakarta.apache.org/struts/dtds/validation_1_1.dtd參閱。

          資源綁定
                資源綁定用于幫助消息本地化和一些其它文本信息的本地化處理。由于它減少了應用程序的許多冗余的硬編碼,故對應用程序有很大益處。比如,如果你要在JSP頁面中要使用一個“Name”標簽時,你可以把這個字符串放到一個資源綁定中,然后使用資源綁定的一個邏輯鍵值引用這個字符串,而不是直接使用這個字符串,這樣做的好處在于,當你想把這個字符串改為“First Name”時,你只需在資源綁定中修改一處即可,而不必修改整個應用程序的全部代碼。
              對于Validator框架,當驗證規則失敗的時候,可以從資源綁定中創建錯誤信息。Validator框架提供幾種默認消息,同一般的應用程序消息資源放在一起。如下:
          application.properties:
          #Normal resource bundle messageslabel.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
          .........

          當一個驗證規則失敗時,這個驗證規則創建一個錯誤信息。框架將自動給消息插入參數。比如說,我們使用例一和例二的驗證規則,當checkoutForm的firstName屬性為空時,我們會看到這樣的錯誤信息:
          First Name is required.
          你也可以修改綁定或配置文件來顯示你喜歡的消息。

          “掛”Validator到Struts上
                 現在我們已經了解了Validator框架,感覺蠻不錯吧!下面我們將快速的講一下我們是如何輕松地在Struts框架中使用Validator框架的。
              首先要做的就是讓Struts框架認識Validator框架。你可以使用Struts1.1的Plug-in新特性來實現它。只要在Struts配置文件中增加下面代碼即可:
          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>

          這樣Struts就可以自動識別Validator框架了。
               另外一個必需的步驟就是創建ActionForm Bean(標準的或是動態的)和確保Validator框架的配置文件是可用的,這樣就搞定了。并不需要作一些調用驗證規則或做其他具體的事情,Struts框架會自動完成這些工作,這就是所謂的基于聲明的配置。然后當驗證規則失敗的時候,你就可以用JSP標簽看到顯示的錯誤信息了。

          創建自己的Validator
                盡管Validator框架已為大家提供了Web應用程序需要的大多數驗證規則,但有時我們還是需要創建一些自己的驗證規則。幸運的,Validator框架的擴展性相當好,為你提供了這種便利,而這樣做對程序造成的影響相當小的。
              創建自己的Validator并不是一件難事,只要創建一個實現這個規則的Java類即可。比如,(在國外)要去超市買二鍋頭,要驗證顧客是否達到合法飲酒年齡。你可以使用已有的驗證規進行驗證,但我們覺得創建一個驗證規則進行驗證要更加直截了一些。驗證飲酒年齡規則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。
          //假設我們已經創建和裝配了一個CheckoutForm Bean對象
          CheckoutForm form = new CheckoutForm();
          //使用chekoutForm創建一個ValidatorValidator 
          validator = new Validator(resources, "checkoutForm");
          //告訴Validator要驗證哪個Beanvalidator.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驗證規則的支持。對于每個<validator>元素,它可以有一個<javascript>子元素和包含一些JavaScript代碼。當包含一些自定義標簽的JSP頁面被解釋時,JavaScript也被解釋,并當表單提交時執行這些驗證規則。這些叫JavaScriptValidatorTag的標簽被包含在Struts的標簽集中。這些標簽可以像這樣進行使用:
          <html:javascript formName="checkoutForm"/>
          筆者認為在需要時使用一定的JavaScript是可以接受的。當你需要執行一些客戶端的驗證時,使用Validator框架標簽是也是一種不錯的選擇,而且支持根據用戶的區域進行本地化。
          結束語
                到此為止,我給大家簡單地介紹了Validator框架,這些其實是框架的一些表面的東西。這個框架的內容深不可測,僅正則表達式就可以寫一本小冊子。
              像任何一個框架一樣,Validator框架為大家提供的是一個基礎的架構,你可以根據你的需求對其進行擴展和個性化。使用像Validator的框架的最重要的一點就是它們是經過千錘百煉,是技術的精華。。你并不需重蹈前人失敗的覆轍,你可以節省下時間把更多的精力集中在對業務邏輯的開發上。

          作者簡介:
          Chuck Cavaness:畢業于Georgia Tech,獲計算機工程與科學學位,在醫療,銀行和B2B領域創建了許多Java企業系統,同時也是O'Reilly的Programming Jakarta Struts 和 Jakarta Struts Pocket Reference兩本書的作者。

          posted on 2006-02-18 10:40 aiyoyoyo 閱讀(208) 評論(0)  編輯  收藏 所屬分類: Struts

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 葫芦岛市| 潢川县| 西贡区| 江口县| 岱山县| 石台县| 汉阴县| 甘谷县| 德兴市| 邹城市| 赣州市| 桂平市| 汶上县| 玛纳斯县| 肃北| 普定县| 旅游| 荥阳市| 宕昌县| 巴中市| 敦煌市| 茂名市| 石林| 侯马市| 崇左市| 美姑县| 措勤县| 尼木县| 安康市| 芷江| 凉城县| 额济纳旗| 应城市| 梁平县| 名山县| 庐江县| 杭州市| 玉田县| 新龙县| 托克托县| 紫阳县|