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

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

轉載請注明來源/作者

?

Struts 學習筆記之ActionForm

?

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

?

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中比較常用的兩個方法是reset()validator()

// 恢復ActionForm屬性的默認值,如把boolean型設為true/false,字符串設為null

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

// validate 只檢查數據格式和語法,不檢查數據是否符合業務邏輯。

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

這兩個方法的默認實現是不執行任何操作,我們可以重寫這兩個方法來實現相關邏輯。

?

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

?

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

?

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

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

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方法,并把數據放到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)"/>

來獲取表單數據,這會調用getAttribute("id")方法。

?

3 . 其中,Dyna開頭的動態ActionForm不需要創建具體的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用來進行表單驗證,驗證方法有兩種。

?

struts-config.xml中設置actionvalidate屬性為"true"(默認為"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>

?

并且在相應的formbean中重寫其中的validate方法,在validate方法中實現自己的數據驗證邏輯。

?

通過validation框架進行驗證,這分為兩步:

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的名字。

?

關于arg的幾個屬性如下:

bundle :指定資源文件名,如不指定,則從默認資源文件中讀取

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

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

position ,這個arg中的值用來替換信息中的哪一部分, 需要替換的部分以{n}標志。

?

5 . 關于ValidatorForm/DynaValidatorFormValidatorActionForm/DynaValidatorActionForm之間的區別

?

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

?

如果需要針對每個action來驗證,則必須使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之間的區別

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 . 上面的驗證是在服務器端進行,如需要在客戶端進行js驗證,需要在頁面上配置:

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

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

用來在提交本頁面時執行相應的js驗證代碼。

?

用來生成本頁面的 js 驗證代碼。 兩種方法

一是 在頁面上聲明

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

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

因為dynamicJavascript/staticJavascriptJavascriptValidatorTag.java默認為true,所以上面也可以直接寫:<html:javascript formName="userForm"/>

struts-html.tld

<tag>

<name>javascript</name>

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

</tag>

?

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

注意只有dynamicJavascript="true" + staticJavascript="true" 才能生成完整的 js 驗證代碼 ,如果把任何一個設為"false"提交頁面時都會產生js錯誤,除非我們采用下面的方法進行聲明。

?

在本頁面上聲明

<%@ 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的內容為

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

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

?

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

?

?

?

附:

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

var bCancel = false;

function validateUserForm(form) {

??? if (bCancel) {

??????? return true;

??? } else {

??????? var formValidationResult;

??????? // 調用staticJavascript.jspstaticJavascript="true"生成的js代碼

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

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

??? }

}

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

// jsFunctionName=" ByteValidations "/>

// 則生成js函數名稱為 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函數名稱為 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) {

??? // ……

??? // 調用 userForm_ ByteValidations ()

??? // ……

}

function validateEmail(form) {

??? // ……

??? // 調用 userForm_ email ()

??? // ……

}

?

?

?

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

?