使Struts支持Validator.. 1Validator-rules.xml文件.... 2Validator.xml 文件.... 2Required Validator.. 3Mask Validator.. 3Range Validator.. 4Maxlength Validator.. 4Minlength Validator.. 5Email Validator.. 5Form Bean的編寫(xiě).... 5Struts-config.xml文件的配置.... 5在JSP頁(yè)面捕捉錯(cuò)誤信息.... 6捕捉服務(wù)端的錯(cuò)誤信息... 6捕捉JavaScript的錯(cuò)誤信息... 6編寫(xiě)擴(kuò)展Struts Validator校驗(yàn)密碼輸入.... 71.編寫(xiě)一個(gè)校驗(yàn)器(Validator),實(shí)現(xiàn)對(duì)form中兩個(gè)字段的一致性校驗(yàn): 72.編寫(xiě)validator-rules文件,增加一個(gè)自定義校驗(yàn)器的配置: 83.編寫(xiě)JSP頁(yè)面... 94.編寫(xiě)validator.xml配置文件: 10支持Validator
要在Struts項(xiàng)目中使用Validator功能,首先需要配置Struts項(xiàng)目,使其支持Validator框架.Struts通過(guò)一個(gè)插件(Plugin)來(lái)使Struts項(xiàng)目支持Validator.這個(gè)Plugin由Struts默認(rèn)提供,用戶也可以自己開(kāi)發(fā)自己的Validator Plugin.Struts默認(rèn)提供的Plugin為:
org.apache.struts.validator.ValidatorPlugIn.
用戶必須在struts-config.xml 文件中配置這個(gè)Plugin,才能使Struts項(xiàng)目支持Validator.配置方法比較簡(jiǎn)單,通過(guò)任何文本編輯器打開(kāi)struts-config.xml 文件,在這個(gè)文件的末尾加上下面的代碼,重新啟動(dòng)J2EE服務(wù)器就可以實(shí)現(xiàn)對(duì)Validator的支持了.
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>
在Jbuilder開(kāi)發(fā)環(huán)境中可以通過(guò)下面的方法使Struts項(xiàng)目支持Validator框架.
1. 在項(xiàng)目管理器中用鼠標(biāo)右鍵點(diǎn)擊Web項(xiàng)目(在我們的項(xiàng)目中是 WebModule ).
2. 選擇菜單的 “Properties…”菜單項(xiàng).
3. 在彈出的對(duì)話框的左邊樹(shù)型結(jié)構(gòu)中選中 “web” 節(jié)點(diǎn).
4. 在右邊的 “JSP/Servlet frameworks” 框中勾選 “sturts1.1” 節(jié)點(diǎn)以及 “struts” 節(jié)點(diǎn)下的 “validation” 子節(jié)點(diǎn).
5. 點(diǎn)擊 “OK” 按鈕完成配置.
6. 檢查 struts-config.xml 文件,可以看到配置文件里已經(jīng)加入了Validator Plugin.
Validator-rules.xml文件
Validator-rules.xml文件是校驗(yàn)器的定義文件.指定了每一個(gè)校驗(yàn)器的基本信息和執(zhí)行校驗(yàn)的JavaScript代碼.Struts默認(rèn)提供了十四個(gè)校驗(yàn)器,這些校驗(yàn)器可以滿足我們平時(shí)項(xiàng)目開(kāi)發(fā)中碰到的絕大多數(shù)的輸入校驗(yàn)要求.如果這些校驗(yàn)器不能滿足用戶的校驗(yàn)要求,那么我們也可以開(kāi)發(fā)自己的校驗(yàn)器.我們項(xiàng)目主就實(shí)現(xiàn)了一個(gè)校驗(yàn)密碼的一致性的Validator.
Struts提供的校驗(yàn)器包括Required Validator ,Requiredif Validator, MinLength Validator , MaxLength Validator , Mask Validator , Byte Validator , Short Validaotr , Integer Validator , Long Validator , Float Validator , Double Validator , Date Validator , Range Validator , IntRange Validator , FloatRange Validator , CrediteCard Validator , Email Validator 等校驗(yàn)器.后面我將講述一些比較常用的校驗(yàn)器的使用方法.
Validator.xml 文件
Validator.xml 文件用來(lái)定義用戶需要校驗(yàn)的每一個(gè)JSP Form中的每一個(gè)字段的校驗(yàn)規(guī)則,這個(gè)文件是我們?cè)赟truts項(xiàng)目開(kāi)發(fā)中使用Validator框架所需要配置的文件.這個(gè)文件的根節(jié)點(diǎn)是<form-validator>,在根節(jié)點(diǎn)下的<formset>節(jié)點(diǎn)的<form>子節(jié)點(diǎn)就對(duì)應(yīng)了我們?cè)陂_(kāi)發(fā)JSP文件是所定義的Form標(biāo)記,也對(duì)應(yīng)這struts-config.xml中的form bean的定義.一個(gè)<form>節(jié)點(diǎn)由多個(gè)<field>節(jié)點(diǎn)組成,每個(gè)<field>節(jié)點(diǎn)的結(jié)構(gòu)大概如下:
<field property="password" depends="required,minlength,twofields">
<msg name="required" key="test.required"/>
<msg name="minlength" key="test.minlength"/>
<msg name="twofields" key="test.twofields"/>
<arg0 key="test.password" />
<arg1 name="minlength" key="${var:minlength}" resource="false" />
<var>
<var-name>minlength</var-name>
<var-value>8</var-value>
</var>
<var>
<var-name>secondProperty</var-name>
<var-value>password2</var-value>
</var>
</field>
其中一個(gè)<Field>對(duì)應(yīng)于一個(gè)Form Bean的一個(gè)Field,<Field>標(biāo)記的property屬性說(shuō)明了這個(gè)Field對(duì)應(yīng)的Form Bean的Field名稱(chēng),這個(gè)名稱(chēng)要跟struts-config.xml文件中的<form-bean>中定義的名字一致.depends屬性說(shuō)明了這個(gè)Field依賴于那些校驗(yàn)器的校驗(yàn),可以使用多個(gè)校驗(yàn)器,各個(gè)校驗(yàn)器之間使用逗號(hào)隔開(kāi).<msg>標(biāo)記說(shuō)明了當(dāng)這個(gè)Field通不過(guò)校驗(yàn)的時(shí)候向用戶提供的錯(cuò)誤信息.name屬性指定了對(duì)應(yīng)的校驗(yàn)器,key屬性指定了定義在ApplicationResources.properties文件中的錯(cuò)誤信息.<arg0>和<arg1>是傳遞給校驗(yàn)器的參數(shù).<var>標(biāo)記定義了參數(shù)的名字和參數(shù)值.上面的這個(gè)例子說(shuō)明了password字段由Required,Minlength,Twofields校驗(yàn)器進(jìn)行校驗(yàn).指定了這個(gè)Field不能為空,而且最小長(zhǎng)度不能小于8為,并且必須和同一個(gè)Form中的另一個(gè)名為password2的字段相同.如果用戶的輸入不能滿足這些要求,校驗(yàn)器將會(huì)拋出異常.
下面開(kāi)始將怎么在這個(gè)配置文件中配置各個(gè)校驗(yàn)器實(shí)現(xiàn)對(duì)form中的多中類(lèi)型的field進(jìn)行校驗(yàn).
Validator
這個(gè)校驗(yàn)器用來(lái)校驗(yàn)Form的輸入數(shù)據(jù)不能為空.如果某一個(gè)Form 的 Field 依賴于這個(gè)校驗(yàn)器,那么如果用戶在Form中沒(méi)有輸入這個(gè)Field對(duì)應(yīng)的輸入數(shù)據(jù)時(shí),Required校驗(yàn)器將會(huì)觸發(fā)一個(gè)Exception,這個(gè)Exception的錯(cuò)誤信息可以在頁(yè)面或者服務(wù)端被捕捉到.
例子:
<field property="test" depends="required">
<msg name="required" key="test.required"/>
<arg0 key="test.testField.displayName"/>
</field>
上面的例子說(shuō)明了test字段的校驗(yàn)規(guī)則是不能為空,在ApplicationResources.properties中的相應(yīng)的定義信息可能是下面這樣的情況:
Test.testField.displayName =測(cè)試字段 #上面在<arg0>標(biāo)記中定義的key= “test.testField” 對(duì)應(yīng)這個(gè)信息
Test.required={0} 不能為空,請(qǐng)重新輸入. #在上面定義的<msg>標(biāo)記對(duì)應(yīng)這個(gè)信息
如果Validator校驗(yàn)到用戶沒(méi)有輸入test這個(gè)字段,就會(huì)將test.testField對(duì)應(yīng)的信息作為test.required的參數(shù)傳遞給校驗(yàn)器,如果在JSP頁(yè)面中捕捉了錯(cuò)誤信息,錯(cuò)誤信息將會(huì)是下面的這個(gè)形式:
“測(cè)試字段 不能為空,請(qǐng)重新輸入”
Validator
Mask Validator校驗(yàn)用戶輸入的數(shù)據(jù)是否遵照一定的規(guī)則,這個(gè)規(guī)則由開(kāi)發(fā)者在validator.xml文件中定義.
例子:
<field property="postalCode" depends="mask">
<arg0 key="test.postalCode.displayname"/>
<arg1 name=”mask” key="${var:mask}" resource="false"
<var>
<var-name>mask</var-name>
<var-value>^0\d*$</var-value>
</var>
</field>
上面的<arg1>標(biāo)記說(shuō)明了這個(gè)校驗(yàn)的第二個(gè)參數(shù)是定義在下面的<var>標(biāo)記的名為mask的值.<var-value>的值說(shuō)明了這個(gè)字段必須是以數(shù)字0開(kāi)頭,以任意數(shù)字字符結(jié)尾的一個(gè)串.
Validator
這個(gè)校驗(yàn)器校驗(yàn)字段是否在一個(gè)數(shù)字范圍內(nèi).
例子:
<field property="age" depends="range">
<msg name="range" key="test.rang"/>
<arg0 key="test.age"/>
<arg1 name="range" key="${var:min}" resource="false"/>
<arg2 name="range" key="${var:max}" resource="false"/>
<var>
<var-name>min</var-name>
<var-value>1</var-value>
</var>
<var>
<var-name>max</var-name>
<var-value>100</var-value>
</var>
</field>
Range Validator需要三個(gè)參數(shù)(arg),第一個(gè)參數(shù)arg0是指定這個(gè)字段的名字,第二個(gè)和第三個(gè)參數(shù)指定范圍的最大和最小值,分別的名稱(chēng)是max和min.
Maxlength Validator
Maxlength校驗(yàn)器校驗(yàn)一個(gè)字符串的最大長(zhǎng)度,它需要兩個(gè)參數(shù),arg0說(shuō)明字段的名稱(chēng),arg1說(shuō)明最大長(zhǎng)度.
例子:
<field property="password" depends="maxlength">
<msg name="maxlength" key="test.minlength"/>
<arg0 key="test.password" />
<arg1 name="maxlength" key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>8</var-value>
</var>
</field>
Minlength Validator
這個(gè)校驗(yàn)器類(lèi)似于上面的Maxlength Validator,參數(shù)一樣,校驗(yàn)規(guī)則也一樣,只是作為參數(shù)的變量名字為minlength
<field property="password" depends="minlength">
<msg name="minlength" key="test.minlength"/>
<arg0 key="test.password" />
<arg1 name="minlength" key="${var:minlength}" resource="false" />
<var>
<var-name>minlength</var-name>
<var-value>8</var-value>
</var>
</field>
Validator
這個(gè)校驗(yàn)器校驗(yàn)電子郵件字段,當(dāng)用戶輸入的電子郵件地址不合法的時(shí)候,校驗(yàn)器拋出異常.
例子:
<field property="email" depends="required,email">
<msg name="required" key="test.required"/>
<msg name="email" key="test.error.email"/>
<arg0 key="test.email"/>
</field>
的編寫(xiě)
要使用Struts的Validator框架進(jìn)行自動(dòng)校驗(yàn)的Form Bean不能繼承自普通的ActionForm,必須繼承自ValidatorForm或者ValidatorActionForm.我們項(xiàng)目組都是繼承自ValidatorForm.
ValidatorForm根據(jù)struts-config.xml文件中的action的name屬性為當(dāng)前form的調(diào)用相應(yīng)的驗(yàn)證器,因此在validator-rules.xml中的<form-bean>元素的名稱(chēng)屬性(name)應(yīng)該與<action>的name屬性值相匹配。
ValidatorActionForm使用struts-config.xml中action的path屬性,所以path屬性的值相應(yīng)的應(yīng)該與validator.xml中的Form的name屬性匹配。
config.xml文件的配置
要使用Validator框架的自動(dòng)校驗(yàn)機(jī)制,還必須在Struts-config.xml文件中作相應(yīng)的配置.除了前面已經(jīng)說(shuō)明了的配置Validator Plugin意外,還需要對(duì)需要校驗(yàn)的form的action進(jìn)行配置.主要有兩個(gè)地方需要配置,一個(gè)是<action>的input屬性,一個(gè)是<action>的validate屬性.input屬性必須指定包含校驗(yàn)Form的jsp頁(yè)面的路徑,以便Struts的校驗(yàn)框架校驗(yàn)失敗的時(shí)候可以重新導(dǎo)向到原來(lái)的頁(yè)面讓用戶重新輸入.validator屬性是一個(gè)boolean類(lèi)型的屬性,必須設(shè)置為true struts才會(huì)啟動(dòng)自動(dòng)校驗(yàn)機(jī)制.
頁(yè)面捕捉錯(cuò)誤信息
Validator的校驗(yàn)機(jī)制可以定義在服務(wù)端進(jìn)行校驗(yàn)或者通過(guò)Javascript在瀏覽器端進(jìn)行校驗(yàn).這兩種不同的方式在JSP頁(yè)面編寫(xiě)的時(shí)候有很大的區(qū)別.
要捕捉服務(wù)端校驗(yàn)的錯(cuò)誤信息比較簡(jiǎn)單.只需要在JSP頁(yè)面中嵌入一下的代碼就可以在頁(yè)面中顯示錯(cuò)誤信息,這些錯(cuò)誤信息也可以自定義顯示風(fēng)格.
<logic:messagesPresent>
<bean:message key="test.error.descript"/>
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</logic:messagesPresent>
<bean:message key=”test.error.descript”/>通過(guò)ApplicationResources.properties文件中定義的信息向用戶報(bào)告錯(cuò)誤發(fā)生的原因和簡(jiǎn)單說(shuō)明.
<html:messages id=”error”>
<li><bean:write name=”error” /></li>
</html:messages>
則是顯示具體的由Validator框架產(chǎn)生的錯(cuò)誤信息.
的錯(cuò)誤信息
要捕捉JavaScript產(chǎn)生的錯(cuò)誤信息首先要使JSP頁(yè)面產(chǎn)生Validator生成的Javascript代碼,并在用戶點(diǎn)擊提交按鈕的時(shí)候讓提交按鈕觸發(fā)相應(yīng)的校驗(yàn)函數(shù).實(shí)現(xiàn)方法如下:
首先要讓JSP觸發(fā)校驗(yàn)函數(shù),使用這樣的HTML代碼:
<html:form action="/testAction.do" onsubmit="return validateTestForm(this);">
其中action指定這個(gè)form對(duì)應(yīng)的action,這個(gè)跟普通的form沒(méi)有區(qū)別,onsubmit屬性就指定了校驗(yàn)函數(shù),它的規(guī)則是: return + 空格 + validator+ ValidatorForm的名字 + (this)
注意這樣的組合規(guī)則是不能變的,否則會(huì)導(dǎo)致頁(yè)面錯(cuò)誤并不能實(shí)現(xiàn)校驗(yàn)功能.還要注意ValidatorForm的名字的第一個(gè)字母一定要大寫(xiě),不管在Struts-congfig.xml文件中的定義是否大寫(xiě),這里都要把它作為大寫(xiě)字母.
然后還要在JSP頁(yè)面中產(chǎn)生可以實(shí)現(xiàn)校驗(yàn)的JavaScript代碼,這個(gè)步驟也很簡(jiǎn)單,只需要在JSP頁(yè)面的末尾加上下面一句:
<html:javascript formName="testForm" staticJavascript="true"/>
其中formName的名字要跟struts-config.xml文件中配置的一致,大小寫(xiě)也要一致.staticJavascript為true的時(shí)候Validator將使用JavaScript代碼進(jìn)行校驗(yàn)(這些Javascript代碼由Struts 的validator框架自動(dòng)產(chǎn)生,我們只需要配置validator.xml文件),staticJavascript為false的時(shí)候validator將使用服務(wù)端代碼進(jìn)行校驗(yàn),這些服務(wù)端的校驗(yàn)代碼也不需要我們編寫(xiě).
alidator校驗(yàn)密碼輸入
使用Struts的validator校驗(yàn)頁(yè)面form中的兩個(gè)字段是否一致,一般用在校驗(yàn)密碼,當(dāng)用戶輸入兩次密碼的時(shí)候需要校驗(yàn)用戶的兩次輸入是否一致,如果不一致需要報(bào)錯(cuò).實(shí)現(xiàn)這個(gè)功能的步驟如下:
編寫(xiě)一個(gè)校驗(yàn)器(Validator),實(shí)現(xiàn)對(duì)form中兩個(gè)字段的一致性校驗(yàn):
package cn.com.syni.net800114.validator;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.GenericValidator;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.validator.Resources;
import javax.servlet.http.HttpServletRequest;
public class 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;
}
}
編寫(xiě)validator-rules文件,增加一個(gè)自定義校驗(yàn)器的配置:
<validator name="twofields"
classname="cn.com.syni.net800114.validator.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>
編寫(xiě)JSP頁(yè)面
form中包括要進(jìn)行自定義校驗(yàn)的字段,這里是兩個(gè)password類(lèi)型的input,校驗(yàn)器將校驗(yàn)用戶輸入的這兩個(gè)字段是否一致,如果不一致,將通過(guò)彈出對(duì)話框告訴用戶:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ page contentType="text/html; charset=GBK" %>
<html:html><head><title>Regiestation</title></head>
<body>
<html:form action="/registationAction.do" onsubmit="return validateRegistation(this);">
<bean:message key="userForm.password"/>
<html:password property="password"/><br>
<bean:message key="userForm.password2"/>
<html:password property="password2"/>
<br>
<html:submit property="submit" value="Submit"/><br>
<html:reset value ="Reset"/>
</html:form>
</body>
<html:javascript formName="registation" staticJavascript="true" dynamicJavascript="true"/>
</html:html>
其中,<html:form action=”/registationAction.do” onsubmit=”return validatorRegistation(this);”>說(shuō)明這個(gè)窗口需要使用Struts Validator進(jìn)行校驗(yàn),action屬性指定這個(gè)JSP頁(yè)面對(duì)應(yīng)的Action,onsubmit屬性指定了這個(gè)頁(yè)面校驗(yàn)所對(duì)應(yīng)的ActionForm Bean,它的規(guī)則是 “return + validator + FormBeanName + (this);”,這里的例子表示這個(gè)頁(yè)面的action是/regiestationAction.do,它對(duì)應(yīng)的Action Form名稱(chēng)為Registation(注意,如果在Struts-config.xml文件中ActionForm的名字為registation的話這里也要把第一個(gè)字母變?yōu)榇髮?xiě),否則出錯(cuò).
最后倒數(shù)第二行的<html:javascrip>標(biāo)記說(shuō)明要使用java script進(jìn)行客戶端校驗(yàn),formName屬性指定Action Form的名稱(chēng),這個(gè)名稱(chēng)要跟struts-config.xml文件中的配置一致,嚴(yán)格區(qū)分大小寫(xiě),staticJavascript和dynamicJavascript分別指定是使用靜態(tài)的還是動(dòng)態(tài)的javascript代碼進(jìn)行校驗(yàn).
編寫(xiě)validator.xml配置文件:
<form name="registation" >
<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.password2" />
<var>
<var-name>secondProperty</var-name>
<var-value>password2</var-value>
</var>
</field>
</form>
這里要注意<var-name>屬性的secondProperty要跟ValidatorUtil.java中的校驗(yàn)方法中的代碼一致,否則ValidatorUtil.java不能正確進(jìn)行校驗(yàn),<var-value>屬性指定這個(gè)校驗(yàn)字段所參照的校驗(yàn)字段,上面的配置代碼說(shuō)明要對(duì)form中的password字段進(jìn)行校驗(yàn),它必須和另外一個(gè)叫做password2的字段一致.
Action里面應(yīng)該寫(xiě)的內(nèi)容:
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
return super.validate(mapping, request);
}