2009-08-26

java Struts Validator驗證器使用指南

Struts Validator驗證器使用指南
Struts Validator驗證器使用指南
(根據Struts Validator Guide)
作者:
David Winterfeldt大衛
James Turner詹姆斯
Rob Leland羅伯特
翻譯:
侯思超
驗證器:
從0.5版,驗證器在一些form中就已經實現了,他最初包含在開發人員包中,後來核心代碼挪到Jakarta
Commons包中和Struts特別擴展中作為 Struts
1.1的一部分。許多開發者為方便一直使用struts驗證器,這篇文檔首先概述驗證器的核心功能性,然後大概介紹在
struts1.1中的變化和新增功能。
如果你配置好驗證器插件,你應該擴展ValidatorForm而不是ActionForm,以便它能載入你的Validator資源。他根據struts-config.xml檔中的action的name屬性為當前form的調用相應的驗證器,因此在validator-rules.xml中的form元素的名稱屬性應該與action的name屬性值相匹配。
另外一種選擇是擴展ValidatorActionForm
而不是ValidatorForm,ValidatorActionForm使用struts-config.xml中action的path屬性,所以path屬性的值相應的應該與validator-rules.xml中的Form的name屬性匹配。
一個分離的action可以定義給多頁form的每個頁面,而且驗證規則可以與action關聯而不是與頁碼,就像驗證範例中的多頁form範例那樣。
國際化
在validator-rules.xml 檔中form的驗證規則可以組織為FormSet。FormSet
有與java.util.Locale 類相應的屬性:如語言, 國家以及變數型屬性,如果他們未定義,FormSet
將把它設置為預設值。一個FormSet 也可以有關聯的常量。另外還可以定義與FormSet
同一級別的全局global元素,他與FormSet同樣也有常量。
注意:你必須在國際化的FormSet前聲明一個沒有國際化的默認FormSet。這樣如果Validator沒有找到locale時可以有一個默認版本。
可插入驗證器的默認錯誤資訊值可以被msg元素覆蓋。所以為mask驗證器生成錯誤資訊的替代方法就是使用msg屬性,如果欄位的name屬性與驗證器的name屬性匹配,那末將使用欄位的msg屬性。
error messages的可以設置arg0-arg3 等參數元素。如果沒有設置arg0-arg3的name屬性,
error messages將使用他們作為默認的構建參數值。如果設置了name屬性,你就可以把參數指定給一特定的可插入驗證器,然後這些參數將在構造錯誤資訊時被使用。
<field
property="lastName"
depends="required,mask">
<msg
name="mask"
key="registrationForm.lastname.maskmsg"/>
<arg0 key="registrationForm.lastname.displayname"/>
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z]*$</var-value>
</var>
</field>
默認的arg0-arg3元素將在消息資源中查找相應的key,如果資源屬性設為false,她將把值直接傳進去,而不從消息資源中查找。注意1.1版本中,你必須為每個模組中明確地定義在驗證中用到的消息資源,否則將使用top-level資源。
<field
property="integer"
depends="required,integer,intRange">
<arg0 key="typeForm.integer.displayname"/>
<arg1
name="range"
key="${var:min}"
resource="false"/>
<arg2
name="range"
key="${var:max}"
resource="false"/>
<var>
<var-name>min</var-name>
<var-value>10</var-value>
</var>
<var>
<var-name>max</var-name>
<var-value>20</var-value>
</var>
</field>
常量/變數
全局的常量可以在全局標籤中定義,FormSet/本地常量能在formset
標籤中創建。常量當前僅僅是代替欄位的property屬性,欄位的var 元素的 value屬性,欄位的msg 元素的
key屬性,欄位的arg0-arg3 元素的 key屬性。欄位的變數也可以在arg0-arg3
元素中被代替(例如:${var:min}))。替換的順序是FormSet/Locale常量第一,全局的常量第二,
arg elements 變數最後。
<global>
<constant>
<constant-name>zip</constant-name>
<constant-value>^\d{5}(-\d{4})?$</constant-value>
</constant>
</global>

<field
property="zip"
depends="required,mask">
<arg0 key="registrationForm.zippostal.displayname"/>
<var>
<var-name>mask</var-name>
<var-value>${zip}</var-value>
</var>
</field>
驗證器可以使用欄位下面的變數部分來存儲變數,這些變數通過欄位的getVar((String key)方法取得。
<field
property="integer"
depends="required,integer,intRange">
<arg0 key="typeForm.integer.displayname"/>
<arg1
name="range"
key="${var:min}" resource="false"/>
<arg2
name="range"
key="${var:max}" resource="false"/>
<var>
<var-name>min</var-name>
<var-value>10</var-value>
</var>
<var>
<var-name>max</var-name>
<var-value>20</var-value>
</var>
</field>
使用validwhen設計複雜的驗證
使用validwhen來設計複雜驗證的一個經常的要求就是根據一個欄位驗證另外一個欄位(比如,
如果你要用戶兩次輸入口令來確認值口令一致),另外一個就是表單中的一個欄位只有另外一個欄位有確定值的時候才是必須輸入的。新的validwhen驗證規則將很快被包含在1.1後的STRUTS版本中,她就是用來處理這種情況的。
validwhen 規則處理單個的變數欄位,叫測試。這變數的值是一個布林的運算式,如果驗證有效則它必須為真。可以包含這種變數的運算式有:
u 單引號或雙引號字串literals,
u 十進位、十六進位、八進制的Integer literals,
u null與null和空字串匹配,
u 其他可以用屬性名引用的form欄位,例如customerAge,
u 可以在外部因用得索引欄位, 例如childLastName[2],
u 可以默認implicit因用得索引欄位, 例如childLastName[], 她將作為被索引的欄位使用同樣的索引到陣列中,
The literal *這�指它包含當前測試欄位的值,
作為例子,考慮一個包含通訊位址和郵箱欄位的form。如果通訊位址不為空則郵箱欄位是必須的required。你能這樣定義validwhen 規則:
<field property="emailAddress" depends="validwhen">
<arg0 key="userinfo.emailAddress.label"/>
<var>
<var-name>test</var-name>
<var-value>((sendNewsletter == null) or (*this* != null))</var-value>
</var>
</field>
上面定義的意思是:如果通訊位址是空或不空時這個欄位時有效的。
這�有個稍微複雜的例子,它使用了索引欄位。假定有一個表單,允許用戶輸入他們希望定購的部件號和數量。類orderLine
的bean的一陣列被用來在稱為orderLines 的一屬性保持輸入項。
If you wished to verify that every line with part number also had a
quantity entered, you could do it with:
如果你希望校驗訂單中有數量輸入得每一行,你可以這樣:
<field
property="quantity"
indexedListProperty="orderLines"
depends="validwhen">
<arg0 key="orderform.quantity.label"/>
<var>
<var-name>test</var-name>
<var-value>((orderLines[].partNumber == null) or (*this* != null))</var-value>
</var>
</field>
這�的意思是:如果相應的partNumber 欄位是空, 或這欄位是不空的,則這欄位是有效的。
最後一個例子,想像一表單,用戶必須輸入他們的以英寸為單位的高度,如果他們在高度在60英寸以下,則出一錯誤。(it is an error
to have checked off nbaPointGuard as a career.)
<field property="nbaPointGuard" depends="validwhen">
<arg0 key="careers.nbaPointGuard.label"/>
<var>
<var-name>test</var-name>
<var-value>((heightInInches >= 60) or (*this* == null))</var-value>
</var>
</field>

給程式師的簡單說明:
所有的比較關係必須在parens 封裝。All comparisons must be enclosed in parens.
只有兩個itme時可以and或or鏈結。
如果比較的兩item都可以轉為整數,則使用numeric比較,否則使用字串比較。
可插入驗證器
驗證是從validation.xml 檔中載入的,默認的驗證規則定義在validation.xml 檔中,默認定義了required,
mask ,byte, short, int, long, float, double, date (沒有本地支持), and a
numeric range。
" mask "方式依賴於預設值安裝要求,那意味著"required "可以完成,在"'mask "將運行以前"required "和"
mask "方式被默認包含進框架中了。任何欄位如果不是"required "而且是空或有零長度將跳過其他驗證。
如果使用了Javascript 標籤,用戶端javascript在validator's javascript
屬性中查找值而且產生一個有驗證form方法的物件,要得到更多的關於Javascript Validator
標籤工作細節的詳細的解釋,參閱html標籤API參考。
"'mask' "方式讓你用一正則運算式遮罩驗證欄位,它使用jakarta的正規運算式包,所有的有效性規則存儲在validator-rules.xml
檔,使用的主類是org.apache.regexp.RE
validation.xml檔中的驗證器配置範例:
<validator name="required"
classname="org.apache.struts.validator.FieldChecks"
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="mask"
classname="org.apache.struts.validator.FieldChecks"
method="validateMask"
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.invalid">

定義可插入驗證器
方法的參數是用逗號分隔的一些類名稱列表,方法屬性需要有一個符合上面的列表的簽名。列表由以下組合而成:
java.lang.Object - 要驗證的Bean。
org.apache.commons.validator.ValidatorAction - 當前ValidatorAction。
org.apache.commons.validator.Field - 要驗證的欄位
org.apache.struts.action.ActionErrors -
如果驗證錯誤將加入ActionError的錯誤物件javax.servlet.http.HttpServletRequest
-當前request 物件。
javax.servlet.ServletContext - 應用的ServletContext。
org.apache.commons.validator.Validator-當前的org.apache.commons.validator.Validator實例。
java.util.Locale - 當前用戶的Locale。
多頁面form
欄位部分有一可選的頁面屬性,它可以被設為整數,頁上欄位的所有驗證小於或等於伺服器端驗證的當前頁,頁上欄位的所有驗證小於或等於用戶端頁上所有欄位的驗證小於或等於伺服器端驗證的當前頁驗證的當前頁。一個mutli-part表單需要定義頁面屬性:
<html:hidden property="page" value="1"/>。
比較兩個欄位
這是一個展示你怎樣才能比較兩個欄位是否有一樣的值的例子。比如"用戶改變他們的口令"一般會有口令欄位和一確認欄位。
<validator name="twofields"
classname="com.mysite.StrutsValidator"
method="validateTwoFields"
msg="errors.twofields"/>
<field property="password" depends="required,twofields">
<arg0 key="typeForm.password.displayname"/>
<var>
<var-name>secondProperty</var-name>
<var-value>password2</var-value>
</var>
</field>

public static boolean validateTwoFields(
Object bean, ValidatorAction va,
Field field, ActionErrors errors, HttpServletRequest request,
ServletContext application) {
String value = ValidatorUtils.getValueAsString( bean, field.getProperty());
String sProperty2 = field.getVarValue("secondProperty");
String value2 = ValidatorUtils.getValueAsString( bean, sProperty2);

if (!GenericValidator.isBlankOrNull(value)) {
try {
if (!value.equals(value2)) {
errors.add(field.getKey(),
Resources.getActionError( application, request, va, field));
return false;
}
} catch (Exception e) {
errors.add(field.getKey(), Resources.getActionError( application,
request, va, field));
return false;
}
}
}
已知的bug
Struts Validator依賴于Commons Validator包,所以問題報告和增強需求可能在兩個產品中列出。
* Struts Validator Bugzilla Reports
* Commons Validator Bugzilla Reports
變更和deprecations
新建的標記屬性。
<html:javascript>標記有新的屬性定義.
使用commons-validator.jar中的DTD驗證。
當前使用的驗證XML檔是根據commons-validator.jar中的DTD。Struts不在為validator-rules.xml
and validator.xml.單獨維護一個分離的DTD,另外,commons-validator
現在維護一個統一的validator.dtd。修改所有validator.xml文件的DTD引用為
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules
Configuration 1.0//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
空欄位。
當前默認在所有得基礎驗證類型中忽略空白的欄位,如果你要求一個欄位必須輸入,那末在你的應用的validator.xml
檔相應的欄位定義的depends屬性中添加 " required "。
新建的範圍RANGE方法.
JavaScript 和JAVA中都添加了intRange & floatRange 方法。
有條件地REQUIRED欄位.
最大的修改是添加了基於其她欄位的值的有條件地require驗證的能力。它允許你定義邏輯如:"只有X欄位非空的時候Y欄位為'male'才有效",這是實現上述邏輯的推薦方法,這種方法在1.1版後的第一版將實現。在1.1版中添加的Requiredif驗證規則,將在新版中去掉。不過,如果你正準備使用requiredif,這�有一個簡短的教程。
讓我們假定你有一個有3個欄位的醫藥的資訊表單,性別sex,懷孕測試pregnancyTest,測試結果testResult,如果性別為'f'
or 'F',則懷孕測試pregnancyTest是required,如果pregnancyTest不是空,測試結果testResult是required。
你的validation.xml 檔的輸入項應該是這樣的:
<form name="medicalStatusForm">
<field property="pregnancyTest" depends="requiredif">
<arg0 key="medicalStatusForm.pregnancyTest.label"/>
<var>
<var-name>field[0]</var-name>
<var-value>sex</var-value>
</var>
<var>
<var-name>fieldTest[0]</var-name>
<var-value>EQUAL</var-value>
</var>
<var>
<var-name>fieldValue[0]</var-name>
<var-value>F</var-value>
</var>
<var>
<var-name>field[1]</var-name>
<var-value>sex</var-value>
</var>
<var>
<var-name>fieldTest[1]</var-name>
<var-value>EQUAL</var-value>
</var>
<var>
<var-name>fieldValue[1]</var-name>
<var-value>f</var-value>
</var>
<var>
<var-name>fieldJoin</var-name>
<var-value>OR</var-value>
</var>
</field>
<field property="testResult" depends="requiredif">
<arg0 key="medicalStatusForm.testResult.label"/>
<var>
<var-name>field[0]</var-name>
<var-value>pregnancyTest</var-value>
</var>
<var>
<var-name>fieldTest[0]</var-name>
<var-value>NOTNULL</var-value>
</var>
</field>
</form>

這�有一個使用索引的屬性更複雜的例子,如果你的struts-config.xml 有這下麵:
<form-bean name="dependentlistForm"
type="org.apache.struts.webapp.validator.forms.ValidatorForm">
<form-property
name="dependents"
type="org.apache.struts.webapp.validator.Dependent[]" size="10"/>
<form-property name="insureDependents" type="java.lang.Boolean"
initial="false"/>
</form-bean>
這�dependentlistForm bean有lastName,firstName,dob,coverageType四個屬性,你可以這樣定義一驗證規則:
<form name="dependentlistForm">
<field
property="firstName" indexedListProperty="dependents" depends="requiredif">
<arg0 key="dependentlistForm.firstName.label"/>
<var>
<var-name>field[0]</var-name>
<var-value>lastName</var-value>
</var>
<var>
<var-name>fieldIndexed[0]</var-name>
<var-value>true</var-value>
</var>
<var>
<var-name>fieldTest[0]</var-name>
<var-value>NOTNULL</var-value>
</var>
</field>

<field
property="dob" indexedListProperty="dependents" depends="requiredif,date">
<arg0 key="dependentlistForm.dob.label"/>
<var>
<var-name>field[0]</var-name>
<var-value>lastName</var-value>
</var>
<var>
<var-name>fieldIndexed[0]</var-name>
<var-value>true</var-value>
</var>
<var>
<var-name>fieldTest[0]</var-name>
<var-value>NOTNULL</var-value>
</var>
</field>

<field
property="coverageType" indexedListProperty="dependents" depends="requiredif">
<arg0 key="dependentlistForm.coverageType.label"/>
<var>
<var-name>field[0]</var-name>
<var-value>lastName</var-value>
</var>
<var>
<var-name>fieldIndexed[0]</var-name>
<var-value>true</var-value>
</var>
<var>
<var-name>fieldTest[0]</var-name>
<var-value>NOTNULL</var-value>
</var>
<var>
<var-name>field[1]</var-name>
<var-value>insureDependents</var-value>
</var>
<var>
<var-name>fieldTest[1]</var-name>
<var-value>EQUAL</var-value>
</var>
<var>
<var-name>fieldValue[1]</var-name>
<var-value>true</var-value>
</var>
<var>
<var-name>fieldJoin</var-name>
<var-value>AND</var-value>
</var>
</field>
</form>
這�的意思是:
如果lastName 欄位是非空的,firstName 欄位required。因為欄位Indexed
為真,這它意味著lastName的indexed 必須與firstName 的索引的一樣,dob同理,除非date不為空。
如果lastName 用樣索引時的值不空, 而且非索引欄位insureDependents為真,則coverageType 是only require。
你可以對欄位在[n]中使用任意數位,唯一的限制是他們必須都是AND或OR,你無法混合使用。
Deprecation:
u JavaScript 和Java的range方法.
u StrutsValidator &StrutsValidatorUtil 類中的Deprecation方法
驗證器api指南
一個簡明的Struts驗證器API指南 可以幫助你開始。
驗證器資源
Struts Validator: Validating Two Fields Match 作者Matt
Raible。(兩個欄位匹配驗證)關於使用方法的文章。(範例部分為翻譯此文內容)
DynaForms and the Validator 作者James Turner and Kevin Bedell。Struts
Kickstart的其中一章(動態form和驗證器),可以自由下載PDF).
Validating user input 作者 David Winterfeldt and Ted Husted。Struts in
Action的其中一章,可以自由下載(PDF)。

使用方法
作者:
醜陋 && Snowtears:經過2周的不懈努力,閱讀了大量的資料,終於對Validator有了個初步的認識,整理了一下,淺淺的談了談寫法,希望能有一定的幫助,其中肯定有許多說的不對不準確的地方,還請多指教
real_herozx@163.net
王藝:
根據以上兩位元的文章正理而成
配置ruts-config.xml:
1、 添加ApplicationResources配置檔。
如:
<!-- ========== Message Resources Definitions =========================== -->
<message-resources parameter="com.dc.sibss.om.struts.ApplicationResources" />
其中com.sibss.om.struts.ApplicationResources"的部分是資源檔案的路徑,此檔的作用是提供錯誤資訊的非編程定制化和多語言支援。如果我們使用中文平臺作業系統,則默認情況下將首先查找ApplicationResource_zh_CN.properties文件,然後是ApplicationResources_zh.properties,如果前兩個檔沒有被找到則將查找ApplicationResources.properties文件。
為了能夠在頁面上顯示錯誤提示資訊,我們還需要將以下內容添加到ApplicationResources.properties文件的末尾:
errors.required={0} is required.
errors.minlength={0} cannot be less than {1} characters.
errors.maxlength={0} cannot be greater than {2} characters.
errors.invalid={0} is invalid.
errors.byte={0} must be an byte.
errors.short={0} must be an short.
errors.integer={0} must be an integer.
errors.long={0} must be an long.
errors.float={0} must be an float.
errors.double={0} must be an double.
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is an invalid e-mail address.
以上僅是struts現在支援的錯誤類型的錯誤提示資訊,如果你自定義了新類型的錯誤驗證,則還需要在此加上你自己的內容。
以上內容中的{0}指的是錯誤提交的參數。比如:當你需要頁面上的"用戶名"不能為空時(也就是上面的errors.required),這個{0}就代表"用戶名",所以如果你沒有填寫用戶名將拋出如下錯誤:
用戶名 is required.(你可以根據需要修改稱中文)
我們可能已經注意到了,既然錯誤提示資訊需要配置,那麼上例中"用戶名"系統是如何得到的呢?沒錯!也是通過修改此配置檔,內容如下:
visitCust.error.name.required=<br>用戶名
這樣當"用戶名"為空時,struts後臺程式將聯合以上兩處定義顯示錯誤資訊。
另外,上面的"visitCust.error.name.required"是在Validation.xml配置驗證內容時指定的。具體見以下介紹。
注意:一般情況下,你的系統只需要一個ApplicationResources檔,所以開發組的成員不要添加自己的resource檔。只有在你的專案分組開發時才需要使用多個ApplicationResources檔,但是,同時你的struts-config.xml檔也會有相同的數量對應。
2、 在struts-config.xml文件中加入validator插件:
加入這個插件後你的應用就具備使用Validator的環境,如:
<!-- ========== Plug Ins Configuration ================================== -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"
property="pathnames" />
</plug-in>
這�如果是想使用多個***.xml檔的話,value部分寫法如下value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml,
/WEB-INF/validation1.xml , /WEB-INF/validation2.xml "
在<action-mappings>�,定義需要驗證的畫面對應的Action的時候要加上validate="true"
四種使用方法
1、 用Javascript在用戶端進行驗證
配置:在需要驗證的JSP檔中寫入
<html:form action="/XXX" onsubmit="return validateXXXX(this);">
這�的XXX 是與要進行驗證的 forward name,validateXXXX (this);�面的XXXX是需要進行驗證的ActionForm名。
<html:javascript formName="mytestForm"/>
在validation.xml檔中寫入驗證代碼就可以進行基本的驗證了。這種方法是在用戶端進行驗證,用戶端可以看到JAVASCRIPT部分的全代碼。安全性不高
2、 ValidatorForm的validate方法
1、validate()方法:使自己的ActionForm繼承ValidatorForm類,在�面編寫自己的方法:
public ActionErrors validate (ActionMapping mapping,HttpServletRequest
request) {
ActionErrors errors = new ActionErrors();
。。。。。。
if ( mytext.equals("aaa") ) {
//my exampleerrors.add("mytext",new ActionError("mytext.error"));
}
。。。。。。
return errors;
}
此時,如果寫了這個方法,就會遮罩掉在Validation.xml中定義的驗證部分,換句話說就是系統運行時,Validation.xml�對應此ActionForm的定義的錯誤驗證部分不實行,如果不寫這個方法的話,系統運行時會進行Validation.xml�對應此ActionForm的定義的錯誤驗證部分的操作。此類方法是在伺服器端進行驗證,驗證部分代碼用戶端不可見。
2、創建你的ActionForm並讓它繼承org.apache.struts.validator.ValidatorForm類。創建你的Action實現,並和上面定義的ActionForm關聯。這�需要注意的是,在定義此Action時一定將validate屬性設置為true,並且在你定義的ActionForm中不要實現它的validate方法----這就意味著你將使用ValidatorForm的validate方法,這樣才能保證你的錯誤驗證正常進行。配置validation.xml文件。基本內容如下:
<form-validation>
<!-- ========== Default Language Form Definitions ===================== -->
<formset>
<form name="custGNewForm">需要驗證頁面上form的名字
<field property="certifiCode"需要校驗的屬性
depends="required,maxlength">校驗內容
<arg0
key="prompt.certifiCode"/>ApplicationResource檔中對應
<arg1 key="${var:maxlength}"
name="maxlength" resouce="false"/>
<var>確定最長限制的長度
<var-name>maxlength</var-name>
<var-value>20</var-value>
</var>
</field>
注意:此處的arg0和arg1就代表了ApplicationResources檔中使用"{}"括起來的參數。比如:
errors.range={0} is not in the range {1} through {2}.
定義了三個參數,所以你這�也要定義<arg0>、<arg1>、<arg2>三個參數才能完整的顯示錯誤資訊。
errors.maxlength={0} cannot be greater than {2} characters.
定義了0、2兩個參數,所以你就需要定義<arg0>和<arg2>兩個參數。
<field property="userName"
depends="required,maxlength">
<arg0 key="prompt.userName"/>
<arg2 key="${var:maxlength}"
name="maxlength" resouce="false"/>
<var>
<var-name>maxlength</var-name>
<var-value>80</var-value>
</var>
</field>
<field property="email"
depends="email">
<arg0 key="prompt.email"/>
</field>
</form>
<form name="custGNewCheckForm">
<field property="certifiCode"
depends="required">
<arg0 key="prompt.certifiCode"/>
</field>
</form>
</formset>
</form-validation>
在校驗頁面的<body>前添加如下內容:<html:errors/>
3、 DynaValidatorForm
不需要再寫對應的ActionForm,只需在struts-config.xml�把自己的ActionForm進行配置:
<form-bean name="testForm" type="org.apache.struts.validator.
DynaValidatorForm">
<form-property name="mytext" type="java.lang.String"/>
<form-property name="mytextarea" type="java.lang.String"/>
<form-property name="mydatetext" type="java.lang.String"/>
</form-bean>
在form-property�設置相應的專案,比如說mytext,mytextarea什麼的,執行的時候會動態生成ActionForm,再在validation.xml�寫入所希望的驗證代碼,就可以了。JSP檔�不需要寫入任何東西,驗證也是在伺服器端進行,驗證部分代碼在JSP中不可見。
4、 組合驗證
如果使用動態驗證DynaValidatorForm的話,不許編寫自己的對應的ActionForm,相應的特殊驗證會受到相當程度的限制。這個時候,需要將特殊驗證部分寫入對應的Action,
if(mytext.equals("aaa")){//My Example
ActionErrors errors = new ActionErrors();
errors.add("***",new ActionError("***.error"));
saveErrors(request,errors);
return (mapping.findForward("false"));
}
就可以實現特殊驗證了。

實際上你的FORM還可以繼承ValidatorActionForm和DynaValidatorActionForm,這兩種與他們對應的ValidatorForm和DynaValidatorForm的唯一區別正如開篇就講到的:在struts-config.xml中查找對應的FORM類時,前者根據ACTION的PATH值,而後者使用NAME值。
範例:
Struts 驗證器:驗證兩個欄位匹配
在使用指南中,有一節講述怎樣創建驗證器來驗證兩個欄位匹配,我用這個伺服器端驗證器(象例子中顯示的那樣)做口令,確定口令驗證。這個已經可以正常工作了;但我還想用用戶端的javascript驗證器來試一試。我寫了自己的程式來比較兩個欄位,但他們和推薦給你的那個不同(from
validator-rules.xml)。所以昨天,我補充了怎樣添加JavaScript方法到validator-rules.xml。
這�就是怎樣配置的的整個過程(大部分在使用指南中已經包含了,保存JavaScript)。
怎樣添加兩個欄位的驗證器
Step 1: 生成一個包含validateTwoFields方法的類。在我的代碼重,我的類定義為ValidationUtil,他有下列方法:

public static boolean validateTwoFields(
Object bean,
ValidatorAction va,
Field field,
ActionErrors errors,
HttpServletRequest request) {

String value = ValidatorUtil.getValueAsString(bean, field.getProperty());
String sProperty2 = field.getVarValue("secondProperty");
String value2 = ValidatorUtil.getValueAsString(bean, sProperty2);

if (!GenericValidator.isBlankOrNull(value)) {
try {
if (!value.equals(value2)) {
errors.add(field.getKey(),
Resources.getActionError(request, va, field));

return false;
}
} catch (Exception e) {
errors.add(field.getKey(),
Resources.getActionError(request, va, field));

return false;
}
}

return true;
}
Step 2: 編輯 validator-rules.xml ,加入"twofields" 規則。
<validator name="twofields" classname="org.appfuse.webapp.util.ValidationUtil"
method="validateTwoFields"
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.twofields">
<javascript><![CDATA[
function validateTwoFields(form) {
var bValid = true;
var focusField = null;
var i = 0;
var fields = new Array();
oTwoFields = new twofields();
for (x in oTwoFields) {
var field = form[oTwoFields[x][0]];
var secondField = form[oTwoFields[x][2]("secondProperty")];

if (field.type == 'text' ||
field.type == 'textarea' ||
field.type == 'select-one' ||
field.type == 'radio' ||
field.type == 'password') {

var value;
var secondValue;
// get field's value
if (field.type == "select-one") {
var si = field.selectedIndex;
value = field.options[si].value;
secondValue = secondField.options[si].value;
} else {
value = field.value;
secondValue = secondField.value;
}

if (value != secondValue) {

if (i == 0) {
focusField = field;
}
fields[i++] = oTwoFields[x][1];
bValid = false;
}
}
}

if (fields.length > 0) {
focusField.focus();
alert(fields.join('\n'));
}

return bValid;
}]]></javascript>
</validator>
Step 3: 在validation.xml中為你的表單配置驗證:
<field property="password" depends="required,twofields">
<msg name="required" key="errors.required"/>
<msg name="twofields" key="errors.twofields"/>
<arg0 key="userForm.password"/>
<arg1 key="userForm.confirmPassword"/>
<var>
<var-name>secondProperty</var-name>
<var-value>confirmPassword</var-value>
</var>
</field>
這�errors.twofields的欄位 '{0}'必須與欄位'{1}' 的值相同。第三步的一個可選的工作就時使用 XDoclet
來生成validation.xml。requires (1) 配置XDoclet (當然)和(2) 在你的表單中添加添加一些@struts
標籤setPassword方法。
/**
* Returns the password.
* @return String
*
* @struts.validator type="required" msgkey="errors.required"
* @struts.validator type="twofields" msgkey="errors.twofields"
* @struts.validator-args arg1resource="userForm.password"
* @struts.validator-args arg1resource="userForm.confirmPassword"
* @struts.validator-var name="secondProperty" value="confirmPassword"
*/
public String setPassword() {
return password;
}

0 留言: