驗(yàn)證用戶(hù)輸入
在大多數(shù)情況下,當(dāng)用戶(hù)通過(guò)表單輸入數(shù)據(jù)時(shí),我們要確保輸入的值有效,然后才能進(jìn)行其他操作,例如將數(shù)據(jù)儲(chǔ)存到數(shù)據(jù)庫(kù)中或用于確定下一步操作。表單驗(yàn)證經(jīng)常使用客戶(hù)端 JavaScript 來(lái)完成。此方法在 WebLogic Workshop 中也適用。此外,服務(wù)器端的驗(yàn)證可在服務(wù)器端檢查用戶(hù)輸入。后一方法的優(yōu)點(diǎn)有:
-
不必依賴(lài)對(duì)其沒(méi)有控制權(quán)的瀏覽器功能。
-
可以使用控制器文件中的其他業(yè)務(wù)邏輯封裝驗(yàn)證邏輯。
-
可以就在受影響表單字段旁的表單中顯示錯(cuò)誤消息,而無(wú)需彈出對(duì)話(huà)框。
客戶(hù)端的驗(yàn)證
WebLogic Workshop 為 netui:form 標(biāo)記及其表單字段提供了許多特性,例如,可以用來(lái)調(diào)用 JavaScript 的 onClick 和 onBlur。例如,可以有 netui:textBox 標(biāo)記,用戶(hù)在其中輸入他們的年齡:
<netui:textBox dataSource="{actionForm.age}" onBlur="isValidAge()"/>
這是 JavaScript 函數(shù) isValidAge 的示例,該函數(shù)在 onBlur 特性中提到:
function isValidAge() { if(document.forms[0].elements[1].value <= 0) alert('Wrong Age'); }
當(dāng)用戶(hù)輸入值并轉(zhuǎn)到下一個(gè)表單字段后,onBlur 特性會(huì)調(diào)用 JavaScript 函數(shù) isValidForm,當(dāng)輸入的年齡認(rèn)為無(wú)效時(shí),該函數(shù)將顯示對(duì)話(huà)框。
請(qǐng)注意,在示例中是使用 JavaScript forms 和 elements 數(shù)組訪問(wèn)表單及其字段的。如果想使用各種字段的正確名稱(chēng),需要使用 tagID 特性以及 WebLogic Workshop JavaScript 函數(shù) getNetuiTagName。還需要用 <netui:html> 替換 <html> 標(biāo)記。重寫(xiě)上一示例,代碼將如下所示:
<netui:html> ... <netui:textBox tagId="age" dataSource="{actionForm.age}" onBlur="isValidAge();"/> ... </netui:html>
而且這將是 JavaScript 函數(shù) isValidAge:
function isValidAge() {
if(document[getNetuiTagName("myForm")][getNetuiTagName("age")].value <= 0)
alert('Wrong Age');
}
請(qǐng)注意,我們使用 getNetuiTagName(而不是 elements[1])來(lái)引用元素的 tagID。也可以推導(dǎo)出,在整個(gè)樣例中,netui:form 標(biāo)記包含 tagID="myForm"(netui:form 標(biāo)記并沒(méi)有實(shí)際顯示在上述樣例代碼中)。
這些方法也可以與表單的提交操作一起使用。對(duì)于 netui:button 和 netui:imageButton 標(biāo)記,可以通過(guò)標(biāo)記的 onClick 特性調(diào)用 JavaScript 函數(shù),如下例所示:
<netui:button value="submit" onClick="return isValidForm();" />
當(dāng)用戶(hù)單擊按鈕時(shí),如果驗(yàn)證成功,JavaScript 函數(shù) isValidForm 會(huì)檢查表單字段并返回 true。或者,如果不是所有的輸入值都正確,isValidForm 函數(shù)顯示帶有錯(cuò)誤消息的對(duì)話(huà)框,并返回 false。(此功能的實(shí)現(xiàn)并沒(méi)有實(shí)際顯示在樣例代碼中。)
對(duì)于 netui:anchor 和 netui:imageAnchor 標(biāo)記(兩者的實(shí)現(xiàn)依賴(lài)于 JavaScript 提交表單),如果驗(yàn)證成功,JavaScript 驗(yàn)證函數(shù)必須包含其他代碼以設(shè)置 JavaScript Form 對(duì)象的 method 和 action 屬性,并調(diào)用其 submit 方法。下列示例(使用與上一示例相同的 tagID 和 JavaScript 函數(shù) isValidForm)說(shuō)明,當(dāng)表單驗(yàn)證成功時(shí)如何設(shè)置各種屬性并調(diào)用 submit 方法:
function submitFromAnchor() { document[getNetuiTagName("myForm")].method="POST"; document[getNetuiTagName("myForm")].action="/ClientSideValidation/thankYou.do"; if(isValidForm()) document[getNetuiTagName("myForm")].submit(); }
如示例所示,表單的 method 屬性必須設(shè)置為 POST。action 屬性必須設(shè)置為當(dāng)用戶(hù)單擊定位點(diǎn)并提交表單時(shí)要調(diào)用的操作的全名。此操作名與 Web 應(yīng)用程序名(后接 JPF 文件中的操作方法名)相對(duì)應(yīng),后接 DO 擴(kuò)展名。在示例中,Web 應(yīng)用程序 ClientSideValidation 的頁(yè)面流 JPF 文件包含操作方法 thank You。
不使用 getNetuiTagName 也可以編寫(xiě)相同的函數(shù),如下例所示:
function submitFromAnchor() { document.forms[0].method="POST"; document.forms[0].action="/ClientSideValidation/thankYou.do"; if(isValidForm()) document.forms[0].submit(); }
最后,netui:anchor 或 netui:imageAnchor 標(biāo)記必須調(diào)用 onClick 特性中的 JavaScript 函數(shù)并添加“return false;”,如下例所示:
<netui:anchor onClick="submitFromAnchor(); return false;" action="thankYou">Submit</netui:anchor>
如果沒(méi)有添加表達(dá)式“return false;”,將始終提交表單,且數(shù)據(jù)不會(huì)發(fā)布到表單 Bean。
服務(wù)器端的驗(yàn)證
WebLogic Workshop 提供兩種完成服務(wù)端驗(yàn)證的方法,一種是在表單 Bean 中使用 Java 來(lái)實(shí)現(xiàn) validate 方法,另一種是使用 Struts ValidatorPlugIn 進(jìn)行基于 XML 的驗(yàn)證。這些示例會(huì)在 WebLogic Workshop 樣例應(yīng)用程序中顯示,并在此處對(duì)其進(jìn)行描述。要獲得樣例代碼,請(qǐng)?jiān)谙铝邪惭b位置開(kāi)始:
<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/...
基于 Java 的驗(yàn)證
要使用表單 Bean 的 validate 方法驗(yàn)證用戶(hù)輸入,請(qǐng)按照此列表中概述的步驟進(jìn)行操作。請(qǐng)注意,這些示例來(lái)自下列樣例頁(yè)面流和相關(guān)文件:
<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/basic
-
將 message-resources 標(biāo)記添加到 JPF 文件中的控制器類(lèi),例如:
/** * @jpf:controller nested="true" * @jpf:message-resources resources="validation.basic.Messages" *
*/ public class Controller extends PageFlowController { ...資源文件位于 Web 項(xiàng)目的 /WEB-INF/classes/... 文件夾下,并具有 properties 擴(kuò)展名。在上例中,Messages.properties 文件位于 /WEB-INF/classes/validation/basic。下文將描述此文件的內(nèi)容。
注意:在示例中,請(qǐng)注意此處使用的對(duì)應(yīng)命名要求。如果消息資源文件是 <project-root>/WEB-INF/classes/validation/basic/Messages.properties,則在 <project-root>/validation/basic/*.jpf 頁(yè)面流批注中引用此文件的方法是 @jpf:message-resources resources="validation.basic.Messages"。
- 將 @jpf:validation-error-forward 批注添加到使用驗(yàn)證的操作。例如:
/** * @jpf:action * @jpf:forward name="success" path="success.jsp" * @jpf:validation-error-forward name="failure" return-to="currentPage" */ public Forward submitForm( Form form ) { return new Forward( "success" ); }
此批注提供靈活的機(jī)制,如果由于運(yùn)行了批注的操作而出現(xiàn)表單驗(yàn)證錯(cuò)誤,它可以指明應(yīng)裝載哪個(gè)頁(yè)面或應(yīng)運(yùn)行哪個(gè)操作。有關(guān)詳細(xì)信息,請(qǐng)參閱 @jpf:validation-error-forward 批注主題。
下列流視圖屏幕說(shuō)明了此樣例頁(yè)面流中的操作和頁(yè)面之間的關(guān)系。
- 將 validate 方法添加到表單 Bean 類(lèi)。此方法必須具有示例中給出的確切簽名:
public ActionErrors validate( ActionMapping mapping, HttpServletRequest request ) { ActionErrors errs = new ActionErrors();
int at = _email.indexOf( '@' ); int dot = _email.lastIndexOf( '.' );
if ( at == -1 || at == 0 || dot == -1 || at > dot ) { errs.add( "email", new ActionError( "badEmail" ) ); }
if ( _zipCode.length() != 5 ) { errs.add( "zipCode", new ActionError( "badZip", new Integer( 5 ) ) ); }
return errs; }
在 validate 方法中,實(shí)現(xiàn)各種表單字段的驗(yàn)證邏輯。如果出現(xiàn)錯(cuò)誤,請(qǐng)?zhí)砑有碌牟僮麇e(cuò)誤。在示例中,zipCode 引用了 JSP (<netui:error value="zipCode"/>) 中的 netui:error 標(biāo)記,badZip 引用了 Messages.properties 文件中的消息密鑰。請(qǐng)注意,new Integer(5) 是錯(cuò)誤字符串中的第一個(gè)替換對(duì)象。例如,在以后的描述中可以看到一個(gè)消息字符串: “The zip code has to be exactly {0} characters.”。這種情況下,Integer(5) 對(duì)象將替換 {0}。ActionErrors 支持最多帶有四個(gè)附加替換對(duì)象的構(gòu)造方法。
有關(guān)完整示例,請(qǐng)參閱<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/basic/Controller.jpf 中的頁(yè)面流控制器類(lèi)。
- 在顯示錯(cuò)誤(通常是表單頁(yè)面)的 JSP 文件中,添加 netui:error 標(biāo)記以顯示錯(cuò)誤消息。例如:
<netui:form action="submitForm">
<table>
<tr>
<td><p>Enter E-mail Address:</p></td>
<td>
<netui:textBox dataSource="{actionForm.email}"/>
</td>
<td>
<netui:error value="email"/>
</td>
</tr>
<tr>
<td><p>Enter 5-digit Zip Code:</p></td>
<td>
<netui:textBox dataSource="{actionForm.zipCode}"/>
</td>
<td>
<netui:error value="zipCode"/>
</td>
</tr>
</table><netui:button>Submit</netui:button> <netui:button action="exit">Exit</netui:button> </netui:form>
在示例中,將在相關(guān)表單字段旁顯示錯(cuò)誤。有關(guān)完整示例,請(qǐng)參閱<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/basic/formPage.jsp。
- 另外(或作為替代方法),可以將 netui:errors 標(biāo)記添加到 JSP (<netui:errors/>),例如在 JSP 底部。此標(biāo)記將顯示所有找到的錯(cuò)誤概要。
- 當(dāng)在 JSP 中顯示錯(cuò)誤時(shí),資源文件包含實(shí)際的錯(cuò)誤消息和要應(yīng)用的任何專(zhuān)用 HTML 格式。請(qǐng)記住,此文件位于 /WEB-INF/classes/... 下,并具有 properties 擴(kuò)展名。在此示例中,Messages.properties 文件位于 /WEB-INF/classes/validation/basic中。
badEmail=Bad email address. badZip=The zip code has to be exactly {0} characters.
errors.header=<br><hr><font color="Blue">List of errors, using the <netui:error> tag:<ul> errors.prefix=<li> errors.suffix= errors.footer=</ul></font>
error.prefix=<font color="Red"> error.suffix=</font>
請(qǐng)注意,在示例中,當(dāng)輸入不正確的 zipCode 時(shí),badZip 是需要顯示的錯(cuò)誤消息的消息密鑰。文件中的其他行創(chuàng)建 netui:error 和 netui:errors 標(biāo)記的格式,以便單個(gè)錯(cuò)誤消息用紅色顯示,錯(cuò)誤概要用藍(lán)色顯示為一個(gè)列表,前加標(biāo)頭“List of errors, using the <netui:error> tag:”。
基于 XML 的驗(yàn)證
要使用 Struts ValidatorPlugIn 驗(yàn)證用戶(hù)輸入,請(qǐng)按照此列表中概述的步驟進(jìn)行操作。請(qǐng)注意,這些示例來(lái)自下列樣例頁(yè)面流和相關(guān)文件:
<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/validator
-
將 message-resources 和 struts-merge 批注添加到 JPF 文件中的控制器類(lèi)。例如:
/** * @jpf:controller nested="true" struts-merge="/WEB-INF/strutsValidator-merge-config.xml" * @jpf:message-resources resources="validation.validator.Messages" * */ public class Controller extends PageFlowController {
...@jpf:controller 批注的 struts-merge 特性會(huì)標(biāo)識(shí)將使用的 Struts 合并文件。此 Struts 合并文件將指向 Struts ValidatorPlugIn 及其規(guī)則。以后會(huì)在此列表中對(duì)合并文件進(jìn)行描述。
資源文件也位于 Web 項(xiàng)目的 /WEB-INF/classes/... 文件夾下,并具有 properties 擴(kuò)展名。在上例中,Messages.properties 文件位于 /WEB-INF/classes/validation/validator。請(qǐng)注意此處使用的對(duì)應(yīng)命名要求。如果消息資源文件是 <project-root>/WEB-INF/classes/validation/validator/Messages.properties,則在 <project-root>/validation/validaor/*.jpf 頁(yè)面流批注中引用此文件的方法是 @jpf:message-resources resources="validation.basic.Messages"。
-
將 @jpf:validation-error-forward 批注添加到使用驗(yàn)證的操作。例如:
/** * @jpf:action * @jpf:validation-error-forward name="failure" return-to="currentPage" * @jpf:forward name="success" path="success.jsp" */ public Forward submitForm( MyForm form ) { return new Forward( "success" ); }此批注提供靈活的機(jī)制,如果由于運(yùn)行了批注的操作而出現(xiàn)表單驗(yàn)證錯(cuò)誤,它可以指明應(yīng)裝載哪個(gè)頁(yè)面或應(yīng)運(yùn)行哪個(gè)操作。有關(guān)詳細(xì)信息,請(qǐng)參閱 @jpf:validation-error-forward 批注主題。
- 在頁(yè)面流中,修改表單 Bean 定義以擴(kuò)展 Struts 的 ValidatorForm 界面:
public static class MyForm extends org.apache.struts.validator.ValidatorForm
有關(guān)此表單 Bean 類(lèi)的完整示例,請(qǐng)參閱 <WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/validator/Controller.jpf。
{
... - 在顯示錯(cuò)誤(通常是表單頁(yè)面)的 JSP 文件中,添加 netui:error 標(biāo)記以顯示錯(cuò)誤消息:
<netui:form action="submitForm">
<table>
<tr>
<td><p>Enter E-mail Address:</p></td>
<td>
<netui:textBox dataSource="{actionForm.email}"/>
</td>
<td>
<netui:error value="email"/>
</td>
</tr>
<tr>
<td><p>Enter Age:</p></td>
<td>
<netui:textBox dataSource="{actionForm.age}"/>
</td>
<td>
<netui:error value="age"/>
</td>
</tr>
</table><netui:button>Submit</netui:button> <netui:button action="exit">Exit</netui:button> </netui:form>
在示例中,將在相關(guān)表單字段旁顯示錯(cuò)誤。有關(guān)完整示例,請(qǐng)參閱<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/validation/validaor/formPage.jsp。
- 另外(或作為替代方法),可以將 netui:errors 標(biāo)記添加到 JSP (<netui:errors/>),例如在 JSP 底部。此標(biāo)記將顯示所有找到的錯(cuò)誤列表。
- 定義 struts-merge 文件以指向 Struts 的默認(rèn)可插接驗(yàn)證器定義文件 validator-rules.xml,以及包含此特定表單的實(shí)際驗(yàn)證規(guī)則的 XML 文件。在示例中,合并文件 strutsValidator-merge-config.xml 定義如下。可以在下列位置找到此合并文件:
<WEBLOGIC_HOME>/samples/workshop/SamplesApp/WebApp/WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"><struts-config> <form-bean/> <global-exceptions/> <global-forwards/> <action-mappings> </action-mappings>
<plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/strutsValidator-validation.xml"/> </plug-in>
</struts-config>
默認(rèn)可插接驗(yàn)證器定義包含在 validator-rules.xml 文件中,該文件位于 WEB-INF 中。實(shí)際的表單驗(yàn)證規(guī)則應(yīng)在單獨(dú)的文件中定義。在示例中,該文件稱(chēng)為 strutsValidator-validation.xml,它也位于 /WEB-INF 中。下面將描述此文件。
- 在 strutsValidator-validation.xml 文件中,使用默認(rèn)驗(yàn)證器定義實(shí)現(xiàn)實(shí)際的表單驗(yàn)證。例如:
<form-validation>
<formset>
<form name="myForm">
<field property="email" depends="required">
<arg0 key="email.displayName"/>
</field>
<field property="age" depends="required,integer">
<arg0 key="age.displayName"/>
</field>
</form>
</formset>
</form-validation> - 當(dāng)在 JSP 文件中顯示錯(cuò)誤時(shí),資源文件包含實(shí)際的錯(cuò)誤消息和要應(yīng)用的任何專(zhuān)用 HTML 格式。請(qǐng)記住,此文件位于 WEB-INF/classes/... 下,并具有 properties 擴(kuò)展名。在此示例中,Messages.properties 文件位于 /WEB-INF/classes/validation/validator 中。
errors.header=<br><hr><font color="Blue">List of errors, using the <netui:error> tag:<ul>
errors.prefix=<li>
errors.suffix=
errors.footer=</ul></font>error.prefix=<font color="Red"> error.suffix=</font>
errors.required={0} is required. errors.integer={0} must be an integer.
email.displayName=The email address age.displayName=The age
請(qǐng)注意,在示例中,email.displayName 描述表單字段名,而 errors.required 描述用于缺少(但必需)表單字段項(xiàng)的錯(cuò)誤消息。如果用戶(hù)沒(méi)有鍵入電子郵件地址,則出現(xiàn)的錯(cuò)誤消息將是“The email address is required”。文件中的其他行創(chuàng)建 netui:error 和 netui:errors 標(biāo)記的格式,以便單個(gè)錯(cuò)誤消息用紅色顯示,錯(cuò)誤概要用藍(lán)色顯示為一個(gè)列表,前加標(biāo)頭“List of errors, using <netui:error> tag:”。