三、自定義校驗(yàn)邏輯
畢竟Struts提供的校驗(yàn)邏輯有限,不可能滿足所有的開發(fā)需要,因此有時(shí)必須對(duì)其進(jìn)行擴(kuò)展。這里舉一個(gè)實(shí)際項(xiàng)目中的例子:校驗(yàn)碼檢查。現(xiàn)在很多網(wǎng)站為了防止惡意的頁面刷新攻擊,都使用了圖片形式的校驗(yàn)碼,如:
表單提交后需要檢查校驗(yàn)碼(存在request或session里)和用戶輸入是否一致,代碼如下:
1
public class MyValidator
{
2
private static Logger logger = Logger.getLogger(Constants.CON_LOGGER_NAME);
3
4
public static boolean validateCodeInput(Object obj,ValidatorAction action,Field field,
5
ActionMessages errors,HttpServletRequest req)
{
6
String code = (String)req.getSession().getAttribute(Constants.SESSION_CHECKSUM_CODE);
7
String input = ValidatorUtils.getValueAsString(obj,field.getProperty());
8
9
logger.debug("Code: " + code + ", input: " + input);
10
if(code.equalsIgnoreCase(input))
11
return true;
12
else
{
13
errors.add(field.getKey(),Resources.getActionMessage(req,action,field));
14
return false;
15
}
16
}
17
}



2

3

4

5



6

7

8

9

10

11

12



13

14

15

16

17

注釋:
1、第1行:MyValidator沒有任何父類,運(yùn)行時(shí)Validator通過reflection生成對(duì)象
2、第4行:校驗(yàn)方法可隨意命名,通過reflection調(diào)用,但參數(shù)必須按照規(guī)范
3、第6行:從session中取出圖片中的字符串
4、第7行:得到用戶輸入的值,Struts在這里用Field類對(duì)表單字段進(jìn)行了封裝,而Field具體封裝的字段在validation.xml中定義,見上篇
validator-rules.xml中的定義:
1
<validator name="codeinput"
2
classname="consultII.web.utils.MyValidator"
3
method="validateCodeInput"
4
methodParams="java.lang.Object,
5
org.apache.commons.validator.ValidatorAction,
6
org.apache.commons.validator.Field,
7
org.apache.struts.action.ActionMessages,
8
javax.servlet.http.HttpServletRequest"
9
msg="errors.code"/>
10

2

3

4

5

6

7

8

9

10

validation.xml中的定義:



在servlet中將校驗(yàn)碼存入session傳遞給Validator:

這樣就OK了。
四、將校驗(yàn)邏輯轉(zhuǎn)譯成JavaScript代碼
由于Validator的代碼在服務(wù)器端被執(zhí)行,因此如果校驗(yàn)請(qǐng)求頻繁的話將會(huì)對(duì)服務(wù)器端造成不小的性能壓力。考慮到這個(gè)問題,Struts中提供的校驗(yàn)方法可以被轉(zhuǎn)譯成JavaScript代碼嵌入頁面,這樣校驗(yàn)將在客戶端進(jìn)行。
使用時(shí),只要在頁面中嵌入兩條Struts html標(biāo)簽庫中的標(biāo)簽:
1
<html:javascript formName = "formName" />
2
<html:form action = "
" onsubmit = "return validateFormName(this);" />

2


其中第一行定義了需要轉(zhuǎn)譯的FormBean名,這里是“formName”,第二行在該FormBean封裝的表單上添加onsubmuit事件,而該事件調(diào)用的函數(shù)會(huì)在JSP請(qǐng)求到客戶端時(shí)由Validator框架自動(dòng)生成,命名規(guī)則為“validateXXX”,其中“XXX”就是第一行中的formName屬性的值,這里是“formName”,因此生成的函數(shù)名為“validateFormName”。
關(guān)于為自定義的Validator(如上文的MyValidator)創(chuàng)建JS代碼,我沒有實(shí)現(xiàn)過,感興趣的話可以去Struts官網(wǎng)上找一下相關(guān)文檔。