配置
Struts Validation
框架
??????
相信正在閱讀本文的讀者都是對
struts
有一定經驗的,對于
struts
到哪去下載、如何安裝配置就不必筆者多言。此處僅僅只討論
struts validation
框架的安裝和配置。通常,我們有
2
種方法來進行這個過程。
-?????????
方法一:
從
struts
自帶的
webapps
目錄下解壓
struts-balnk.war
到項目的
web
工程目錄。這是最簡單創建
struts
工程的方式,在這個工程中就已經包含了一個
struts
應用的所有需要的開發包和這些包的基本配置,自然也包含了其中的
validation
框架。它非常適合在項目的初創階段,我們所需做的就是在這個空白工程中填點什么就可以了。
-?????????
方法二:
對于已經存在的
struts
工程,如何添加
valiadation
框架支持所需的步驟也非常簡單。
1.??????
首先在
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>
2.??????
然后在
web-inf
目錄中創建
2
個文件
validator-rules.xml
,
validation.xml
。(這
2
個文件也可從
struts-balnk.war
中獲取)。
3.??????
復制
validation
框架所需要的類包到
web-inf/lib
下,這些類包是:
common-validator.jar
。
這樣,我們就可以使用
struts
的
validation
框架了。
使用
validation
框架
?????
問題
??????
這是一個簡單的用戶管理程序,使用者可以對用戶信息進行相應的
CRUD
操作(增查改刪)。其中用戶信息包含用戶名稱、用戶地址、用戶描述、用戶密碼。對于以上的各種操作,約束如下:
-?????????
增加和修改:用戶名稱、用戶地址、用戶密碼、用戶密碼確認為必填項,同時密碼和確認密碼
2
個域的值必須一致。
-?????????
刪除和查詢:用戶名稱為必填項。
解決和使用步驟
1.??????
創建
struts
項目的基本環境。
2.??????
創建相應的頁面,確定頁面流程(
page flow
)。
3.??????
創建相應的
formbean
:
2???????
strut1.1
版本解決辦法:
為了簡單起見使用
DynaActionForm
。又由于使用了
validation
框架,此處使用
DynaValidatorForm
。
struts-config.xm
的內容:
<form-bean name="editForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="id" type="java.lang.Integer"/>
<form-property name="name" type="java.lang.String"/>
???? <form-property name="pwd1" type="java.lang.String"/>
???? <form-property name="pwd2" type="java.lang.String"/>
<form-property name="address" type="java.lang.String"/>
<form-property name="desc" type="java.lang.String"/>
</form-bean>
然后,修改
web-inf
目錄下的
validation.xml
文件內容,其中
form
的名字和各域的名字必須和
struts-config.xml
中一致:
<form name="/editForm ">
???? <field property="name" depends="required">
????????? <arg0 key="editForm.name"/>
???? </field>
???? <field property="pwd1" depends="required,mask">
??
??
?
????<arg0 key="editForm.password"/>
????????? <var>
??????????????? <var-name>mask</var-name>
??????????????? <var-value>^[0-9a-zA-Z]*$</var-value>
????????? </var>
???? </field>
???? <field property="pwd2" depends="required,mask">
????????? <arg0 key="editForm.password"/>
????????? <var>
??????????????? <var-name>mask</var-name>
??????????????? <var-value>^[0-9a-zA-Z]*$</var-value>
????????? </var>
???? </field>
<field property="address" depends="required ">
????????? <arg0 key="editForm.address"/>
???
?</field>
</form>
4.??????
創建相應的
Action
,同時
Action
的
validate
屬性置為
true
,以啟用
validation
框架。
5.??????
書寫
ApplicationResources.properties
,添加錯誤信息。
2???????
struts1.1
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.
?
errors.byte={0} must be a byte.
errors.short={0} must be a short.
errors.integer={0} must be an integer.
errors.long={0} must be a long.
errors.float={0} must be a float.
errors.double={0} must be a double.
?
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}.
errors.creditcard={0} is an invalid credit card number.
errors.email={0} is an invalid e-mail address.
?
editForm.name= name.
editForm.password= password.
editForm.address= address
6.??????
在相應的
jsp
中添加
<html:errors property="age"/>
從整個使用過程來看,就驗證部分而言,使用
struts1.1
的開發效率大大的得到了提高,而且通過
validator-rules.xml
使驗證方法能被不同的
formbean
復用,而且可維護性也大大的得到提高。通過
mask
,使得單個頁面域的驗證非常靈活。
但是細心的讀者可能也發現了這個驗證文件僅僅指明
2
個
password
域是必填的,但并沒有滿足他們必須是相等的這種情形的判斷,對于這一點,我們可使用自定義的
validator
并將它添加到
validator-rules.xml
文件中來完成。
創建自定義的
validator
??????
對于
validator
的創建,可以歸結為
3
步:
1.??????
創建
validator
類,
validator
必須包含一個以
validate
開始的方法,并且它的函數簽名必須如下:
validateXXX(java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,? org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest,? javax.servlet.ServletContext)
在本例中,自定義的
Validator
如下(摘至
Struts
提供的例子,用來提供
2
個域的相等性檢查):
?????????????
public class CustomValidator {
public CustomValidator() {
super();
}
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;
}
}
2.??????
添加到
validator-rules.xml
文件中:
<validator name="twofields" classname="examples.validator.CustomValidator"
???? 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"
msg="errors.twofields" />
??????????????????
在對應的屬性文件中添加對應的消息(
errors.twofiled
)。
3.??????
在
validation.xml
中使用:
<field property="pwd1" depends="required,twofields">
???????? <arg0 key="editForm.password" />
?????????? <arg1 name="twofields" key=" editForm.password2" />
?????????? <var>
??????????????????? <var-name>secondProperty</var-name>
??????????????????? <var-value>pwd2</var-value>
?????????? </var>
</field>
????????
通過自定義
validator
,
validation
框架的可擴展性大大的得到提高。而且也使得不同的驗證方法能夠很好的得到復用
javascript
支持
??????
在
web
應用中,使用
javascript
的機會非常多。雖然不少書上提及客戶有可能從瀏覽器關閉
js
的執行,但是要想完全的不使用它,目前看來好像還不行。比如一些復雜的
UI
是必須通過
js
來實現的(如下拉式菜單等等)。那么
validation
框架支不支持客戶端的
js
驗證呢?
答案是:當然。具體做法是:
-?????????
在頁面
html:form
標簽內部添加
onsubmit="return validateEditForm(this);"
(具體的語法:
validate+
在
validation.xml
文件中定義的
form
的名字);如:
<html:form action="<%=action%>" method="post" onsubmit="return validateEditForm(this);">
-?????????
在
html:form
內部塊中添加:
<html:javascript formName="editForm"/>
??????
如此
2
步即可。雖然,
validation
框架非常簡單易用,但是還是有需要注意的地方。
使用注意
1.??????
使用
validation
框架后,
form
必須從
ValidatorForm
中派生,同時必須在你的
validate
方法中先調用基類的
validate
方法。對于使用
Dyna
開頭的方法來創建
formbean
的讀者,你也必須改為以
dyna
開頭含有
validator
的
form
。
2.??????
注意
DynaValidatorForm
(
ValidatorForm
)和
DynaValidatorActionForm
(
ValidatorActionForm
)的區別。剛開始時從幫助中沒看明白這
2
者的區別,后來從網上一篇文章中得到了用法的區別。前者主要的視角是
formbean
,而后者的視角是
action
。
當
formbean
被不同的
action
使用時,對于不同的
action
而言,使用的
formbean
的屬性集合有大有小。此時如果仍然以
formbean
為主體,會造成其他
action
的不正常使用。因此,
struts
中提出了
DynaValidatorActionForm
(
ValidatorActionForm
)。此時在
validation.xml
中的
form
標簽的
name
屬性改為
action
的
path
屬性,又由于
action
中有
attribute
和
name
屬性,
validation
框架就可根據這個
action
得到對應的
formbean
。例子:
<formset>
? <form name="/createAddress">
??? <field property="city"
????????? depends="required">
????? <arg0 key="prompt.city"/>
??? </field>
? </form>
? <form name="/editAddress">
??? <field property="state"
????????? depends="required">
????? <arg0 key="prompt.state"/>
??? </field>
? </form>
</formset>
3.??????
與
DispatchAction
的配合。
Struts1.1
的
DispatchAction
使得相關的
Action
的關系緊密,大大減少了應用中
Action
的個數,但是隨之而來也帶來了使用
Validation
框架的不便,不能不說是一個遺憾。讀者也許認為這種情況可以使用第
2
條的解決方案來解決,即采用
DyanValidatorActionForm
,然后在
Validation.xml
文件中
form
的名稱使用不同的
Actiond
的
path
,即在
validation.xml
中使用:
<form name="/user.do?method=doAdd">
、
??? <form name="/user.do?method=doLoad">
。然而,在目前的版本中
Validation
框架并不支持這種辨認。一種繞過這個情況的方法是,針對同一個
Action
實現類在
Struts-config.xml
文件中定義多個
Action
的
path
,在不需要進行驗證的地方將
Action
的
validate
屬性置為
false
。即:
struts-config.xml
:
<action attribute="editForm" path="/user" name="editForm" input="/editUser.jsp"
parameter="method" scope="request" type="foxgem.struts.UserDispatchAction"
???? validate="true">
?????????????? <forward name="load" path="/editUser.jsp"/>
?????????????? <forward name="action" path="/userquery.do?pageId=1"/>
</action>
???????
<action attribute="editForm" path="/loaduser" name="editForm" input="/editUser.jsp"
???????
? parameter="method" scope="request" type="foxgem.struts.UserDispatchAction"
???????
? validate="false">
?????????????? <forward name="load" path="/editUser.jsp"/>
?????????????? <forward name="action" path="/userquery.do?pageId=1"/>
</action>
然后在
validation.xml
文件中使用
2
的方法。
結束語
??????
總的說來,
validation
框架大大的提高了頁面驗證的開發效率,更吸引人的是這些驗證方法可通過自定義的
validator
來得到復用。使得這些驗證代碼更加集中,可維護性得到加強。當然隨著項目的進行,
validation.xml
和
validator-rules.xml
會隨之增長,這部分的維護工作加重了。
??????
同時,由于不能非常好的和
DispatchAction
一起協作,也使得大量使用
DispatchAction
的項目不能非常好的使用它。建議大量使用
DispatchAction
和頁面驗證非常復雜多變的項目可以暫時按原來的方法來驗證,不使用
validation
框架。
??????
至于
validation
框架的其他詳細信息,請參見
struts
的文檔,在此不再贅述。
關于作者
胡鍵,西安交通大學工學碩士,熱衷于
j2ee/.net
技術,是
OpenSource
的忠實擁護者。目前與友人創建西安爍程軟件有限公司。公司主要致力于
java web
應用的開發,已有多個項目在能源、電力和交通行業得到應用。可以通過
james.hu@chinacodeline.com
與他取得聯系。