版權(quán)所有:(xiaodaoxiaodao)藍(lán)小刀 ?? xiaodaoxiaodao@gmail.com

http://m.tkk7.com/xiaodaoxiaodao/archive/2007/05/31/121264.html ??? ??

轉(zhuǎn)載請注明來源/作者

?

Struts 學(xué)習(xí)筆記之ActionForm

?

Struts 中定義了一些JavaBeans,主要是以ActionForm為父類擴(kuò)展開來的,如下圖:

?

actionform.JPG?

org.apache.struts.action包中

public abstract class ActionForm implements Serializable

public class DynaActionForm extends ActionForm implements DynaBean

?

org.apache.struts.validator包中

public class ValidatorForm extends ActionForm implements Serializable

public class DynaValidatorForm extends DynaActionForm

implements DynaBean, Serializable

?

org.apache.struts.validator包中

public class ValidatorActionForm extends ValidatorForm implements Serializable

public class DynaValidatorActionForm extends DynaValidatorForm

??? implements DynaBean, Serializable

?

1 ActionForm中比較常用的兩個(gè)方法是reset()validator()

// 恢復(fù)ActionForm屬性的默認(rèn)值,如把boolean型設(shè)為true/false,字符串設(shè)為null

public void reset( ActionMapping mapping, HttpServletRequest request ) { }

// validate 只檢查數(shù)據(jù)格式和語法,不檢查數(shù)據(jù)是否符合業(yè)務(wù)邏輯。

public ActionErrors validate( ActionMapping mapping, HttpServletRequest request ) { return (null); }

這兩個(gè)方法的默認(rèn)實(shí)現(xiàn)是不執(zhí)行任何操作,我們可以重寫這兩個(gè)方法來實(shí)現(xiàn)相關(guān)邏輯。

?

注: 對于每個(gè)request,控制器都會先調(diào)用ActionFormreset()方法,然后表單數(shù)據(jù)組裝到ActionForm中。如ActionFormrequest范圍內(nèi),那么對于每個(gè)新的request請求都會創(chuàng)建新的ActionForm實(shí)例。新實(shí)例創(chuàng)建后,如果它的屬性已經(jīng)被初始化為默認(rèn)值,那么接著再在reset()方法中把屬性設(shè)為默認(rèn)值不是很有必要,這時(shí)可以讓reset()方法為空。

?

對于session范圍內(nèi)的ActionForm,同一ActionForm實(shí)例會被多個(gè)請求共享,reset()方法在這種情況下極為有用。

?

2 . 其中,ActionForm需要我們創(chuàng)建一個(gè)formbean類繼承ActionForm,在ActionForm中可以定義一些propertyget/set方法。

ActionForm property必須聲明然后才可以使用,不過在查詢時(shí)我們常常需要輸入一些查詢條件,這些查詢條件(property)其實(shí)不需要在formbean中聲明,這時(shí)可以使用Map對象來封裝整個(gè)查詢表單提交的數(shù)據(jù),如下:

public class MapForm extends ActionForm {

??? private Map map = null;

??? public void setMap(Map map) {

??????? this.map = map;

??? }

??? public Map getMap() {

??????? return this.map;

??? }

?? ?// 增加查詢條件(property)的get/set方法,并把數(shù)據(jù)放到Map

??? public void setAttribute(String attributeKey, Object attributeValue) {

??????? map.put(attributeKey, attributeValue);

??? }

??? public Object getAttribute(String attributeKey) {

??????? Object keyValue = map.get(attributeKey);

??????? return keyValue;

??? }

}

?

在頁面上可以通過

<html:text property="attribute(id)"/>

來獲取表單數(shù)據(jù),這會調(diào)用getAttribute("id")方法。

?

3 . 其中,Dyna開頭的動(dòng)態(tài)ActionForm不需要?jiǎng)?chuàng)建具體的ActionForm類,只需通過Struts的配置文件就可以完成ActionForm的全部配置,如:

<form-bean name="optionsForm" type="org.apache.struts.action.DynaActionForm">

??? <form-property name="fruit1" type="java.lang.String" initial="Pear" />

??? <form-property name="fruit2" type="java.lang.String" initial="Apple" />

</form-bean>

?

4 . 其中,含有validatorActionForm用來進(jìn)行表單驗(yàn)證,驗(yàn)證方法有兩種。

?

struts-config.xml中設(shè)置actionvalidate屬性為"true"(默認(rèn)為"true"),

<action path="/updateUser"

??????? type="com.cn.lively.action.UpdateUserAction"

??????? name="userForm"

??????? scope="request"

??????? input="/jsp/updateUser.jsp"

??????? cancellable="true"

??????? validate="true" >

??? <forward name="success" path="/jsp/validator/updateUserResults.jsp"/>

</action>

?

并且在相應(yīng)的formbean中重寫其中的validate方法,在validate方法中實(shí)現(xiàn)自己的數(shù)據(jù)驗(yàn)證邏輯。

?

通過validation框架進(jìn)行驗(yàn)證,這分為兩步:

struts-config.xml中配置validation插件,

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

??? <set-property property="pathnames"

????????????????? value="/org/apache/struts/validator/validator-rules.xml,

???????????????????????? /WEB-INF/validation.xml" />

</plug-in>

?

配置formbean,有下面兩種方法:

?

使自己的formbean類繼承含有validatorActionForm

public class UserForm extends ValidatorForm{

??? private String userName;

??? public String getUserName() {

??????? return userName;

??? }

??? public void setUserName(String userName) {

??????? this.userName = userName;

??? }

}

并配置struts-config.xml文件:

<form-bean name="userForm" type="com.cn.lively.formbean.UserForm">

</form-bean>

?

使自己的formbean類繼承含有validatorDynaValidatorForm

<form-bean name="userForm" type="org.apache.struts.validator.DynaValidatorForm">

??? <form-property name="userName" type="java.lang.String" />

</form-bean>

?

配置validation.xml文件:

<formset>

??? <form name="userForm">

??????? <field property="userName" depends="required">

??????????? <arg key="userForm.userName" />

??????? </field>

??? </form>

</formset>

?

注: 注意 validation.xml文件中的userFormstruts-config.xml文件中formbean的名字。

?

關(guān)于arg的幾個(gè)屬性如下:

bundle :指定資源文件名,如不指定,則從默認(rèn)資源文件中讀取

key :從資源文件 ActionResources.properties 中得到的值

resource key所指定的信息是否來自外部的資源文件,默認(rèn)為true。如果為true,則代表keybuddle屬性所指定的資源文件中的key

position ,這個(gè)arg中的值用來替換信息中的哪一部分, 需要替換的部分以{n}標(biāo)志。

?

5 . 關(guān)于ValidatorForm/DynaValidatorFormValidatorActionForm/DynaValidatorActionForm之間的區(qū)別

?

對于一個(gè)actionform,可以被多個(gè)action所使用,而每個(gè)action可能需要的驗(yàn)證字段都不一樣,而validation.xml中配置的驗(yàn)證方式(如<form name="userForm">)是對這個(gè)formbean進(jìn)行的.

?

如果需要針對每個(gè)action來驗(yàn)證,則必須使formbean繼承ValidatorActionForm(或者直接配置DynaValidatorActionForm)。如下兩種方法:

使自己的formbean類繼承含有validatorActionForm

public class UserForm extends ValidatorActionForm{

??? ……

}

并配置struts-config.xml文件:

<form-bean name="userForm" type="com.cn.lively.formbean.UserForm">

</form-bean>

?

<action-mappings>

??? <action path="/createUser"

??????????? type="com.cn.lively.action.CreateUserAction"

??????????? name="userForm"/>

??? <action path="/updateUser"

??????????? type="com.cn.lively.action.UpdateUserAction"

??????????? name="userForm"/>

</action-mappings>

?

使自己的formbean類繼承含有validatorDynaValidatorActionForm

<form-bean name="userForm" type="org.apache.struts.validator.DynaValidatorActionForm">

??? <form-property name="userName" type="java.lang.String" />

</form-bean>

?

<action-mappings>

??? <action path="/createUser"

??????????? type="com.cn.lively.action.CreateUserAction"

??????????? name="userForm"/>

??? <action path="/updateUser"

??????????? type="com.cn.lively.action.UpdateUserAction"

??????????? name="userForm"/>

</action-mappings>

?

配置validation.xml文件:

<formset>

??? <form name="/createUser">

??????? <field property="userName" depends="required">

??????????? <arg key="userForm.userName" />

??????? </field>

??? </form>

??? <form name="/updateUser">

??????? <field property="userName" depends="maxlength">

??????????? <arg key="userForm.userName" />

??????????? <arg key="prompt.max" position="0"/>

??????????? <arg name="maxlength" key="${var:maxlength}" resource="false" ????????????????? ??? position="1" />

??????????? <var>

??????????????? <var-name>maxlength</var-name>

??????????????? <var-value>10</var-value>

??????????? </var>

??????? </field>

??? </form>

</formset>

?

注: 注意validation.xml文件中的/createUser/updateUserstruts-config.xml文件中actionpath路徑。

?

如果我們查看struts源碼,可以很清楚的看到ValidatorForm/DynaValidatorFormValidatorActionForm/DynaValidatorActionForm之間的區(qū)別

ValidatorForm 中的方法

* @return validation key - the form element's name in this case

public String getValidationKey(ActionMapping mapping,

??????? HttpServletRequest request) {

??????? return mapping.getAttribute(); ?// 返回formbean的名字

}

?

ValidatorActionForm 中的方法

* @return validation key - the action element's 'path' attribute in this * case

public String getValidationKey(ActionMapping mapping,

??????? HttpServletRequest request) {

??????? return mapping.getPath();? // 返回action的路徑

}


7 . 上面的驗(yàn)證是在服務(wù)器端進(jìn)行,如需要在客戶端進(jìn)行js驗(yàn)證,需要在頁面上配置:

<html:form action="/ createUser" onsubmit="return validateUserForm(this);">

格式為 return validate + formbean名稱(首字母大寫) + (this)

用來在提交本頁面時(shí)執(zhí)行相應(yīng)的js驗(yàn)證代碼。

?

用來生成本頁面的 js 驗(yàn)證代碼。 兩種方法

一是 在頁面上聲明

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:javascript formName="userForm" dynamicJavascript="true" staticJavascript="true"/>

因?yàn)?span lang="EN-US">dynamicJavascript/staticJavascriptJavascriptValidatorTag.java默認(rèn)為true,所以上面也可以直接寫:<html:javascript formName="userForm"/>

struts-html.tld

<tag>

<name>javascript</name>

<tag-class>org.apache.struts.taglib.html.JavascriptValidatorTag</tag-class>

</tag>

?

注: 在客戶端執(zhí)行的js驗(yàn)證如果不通過,會alert出對話框進(jìn)行提示,服務(wù)器 的驗(yàn)證(在頁面上可以用<html:errors/>來顯示出錯(cuò)信息)就不會執(zhí)行。

注意只有dynamicJavascript="true" + staticJavascript="true" 才能生成完整的 js 驗(yàn)證代碼 ,如果把任何一個(gè)設(shè)為"false"提交頁面時(shí)都會產(chǎn)生js錯(cuò)誤,除非我們采用下面的方法進(jìn)行聲明。

?

在本頁面上聲明

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:javascript formName="userForm" dynamicJavascript="true" staticJavascript="false"/>

<script language="Javascript1.1" src="staticJavascript.jsp"/></script>

定義staticJavascript.jsp的內(nèi)容為

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:javascript dynamicJavascript="false" staticJavascript="true"/>

?

注: dynamicJavascript 表示是否在頁面內(nèi)生成動(dòng)態(tài)的jsstaticJavascript屬性代表是否在頁面內(nèi)生成靜態(tài)js。 如staticJavascript設(shè)為"true",則validator-rules.xml文件中的規(guī)則檢查生成的js代碼都會生成到本頁面內(nèi)。這樣本頁面會越來越大,一般最好是將staticJavascript設(shè)為"false", 將validator-rules.xml生成的js代碼填充到一個(gè)指定的jsp頁面(staticJavascript.jsp)中去。

?

?

?

附:

只有 dynamicJavascript="true" + staticJavascript="true" 才能生成完整的 js 驗(yàn)證代碼 ,下面是 dynamicJavascript="true"生成的參考代碼:

var bCancel = false;

function validateUserForm(form) {

??? if (bCancel) {

??????? return true;

??? } else {

??????? var formValidationResult;

??????? // 調(diào)用staticJavascript.jspstaticJavascript="true"生成的js代碼

??????? formValidationResult = validateByte(form) && validateEmail(form);

??????? return (formValidationResult);

??? }

}

// validator-rules.xml 中定義了<validator name="byte"

// jsFunctionName=" ByteValidations "/>

// 則生成js函數(shù)名稱為 formbean 名稱 + 下劃線 + jsFunctionName

function userForm_ByteValidations() {

??? this.a0 = new Array("byteValue", "Byte must be a byte.", new Function ("varName", " return this[varName];"));

}

// validator-rules.xml 文件中沒有定義jsFunctionName<validator name=" email "/>

// 則生成js函數(shù)名稱為 formbean 名稱 + 下劃線 + validator name

function userForm_email() {

??? this.a0 = new Array("email", "Email is an invalid e-mail address.", new Function ("varName", " return this[varName];"));

}

?

下面 staticJavascript.jsp staticJavascript="true" 生成的參考代碼:

function validateByte(form) {

??? // ……

??? // 調(diào)用 userForm_ ByteValidations ()

??? // ……

}

function validateEmail(form) {

??? // ……

??? // 調(diào)用 userForm_ email ()

??? // ……

}

?

?

?

版權(quán)所有:(xiaodaoxiaodao)藍(lán)小刀?? xiaodaoxiaodao@gmail.com

?