一、動態Form簡介
雖然ActionForm功能強大,但有些時候使用起來有些麻煩。如每建立一個用戶錄入界面(JSP頁面),就得建立一個ActionForm子類來和這個頁面對應。當然,我們可以采用嵌套屬性從一定程度上彌補這個問題。但是在建立新的用戶錄入界面時,仍不可避免地要建立新的ActionForm子類。
在Struts1.2.6及以後的Struts版本中提供了一種動態Form的技術。使得不用再建立新的ActionForm就可以封裝用戶提交的數據。實際上,這種技術將定義ActionForm子類的工作變成了編寫XML文件的工作。
每定義一個動態Form,就要在struts-config.xml中加一個<form-bean>元素,並使用<form-property>子元素來定義動態Form的屬性。
在本章的最後還會介紹一個LazyValidatorForm類,通過這個類甚至可以不定義動態Form的屬性就可以使用動態Form。這將大大簡化開發人員的工作量。
二、聲明動態Form
聲明一個動態Form非常簡單,只需要在struts- config.xml的<form-beans>元素中加入一個<form-bean>子元素,並使用<form- property>元素來定義動態Form的屬性。我們可以定義的屬性類型有簡單屬性(如String)、索引屬性(如數組)、映射屬性(如 HashMap)以及嵌套屬性(屬性類型是另一個類)。
對於動態Form來說,Form的類型必須是org.apache.struts.action.DynaActionForm或其子類。聲明一個動態Form的代碼如下:
<form-bean name="dynamicForm" type="org.apache.struts.action.DynaActionForm">
<!-- 聲明一個簡單屬性 -->
<form-property name="simpleProp" type="java.lang.String" initial="bill"/>
<!-- 聲明一個索引屬性 -->
<form-property name="indexedProp" type="java.lang.String[]" />
<!-- 聲明一個映射屬性 -->
<form-property name="mappedProp" type="java.util.HashMap" />
<!-- 聲明一個嵌套屬性 -->
<form-property name="nestedProp" type="com.bean.MyBean" />
</form-bean>
三、動態Form的屬性類型
下面列出了動態Form支持的簡單屬性的所有類型:
java.math.BigDecimal
java.math.BigInteger
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Class
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Short
java.lang.String
java.sql.Date
java.sql.Time
java.sql.Timestamp
實際上,上面的數據類型就是Java中提供了簡單數據類型。它們用在動態Form中和在Java中代表的數據類型是完全一樣的。我們還可以使用<form-property>元素的initial屬性為動態Form的簡單屬性指定一個默認值。如在例程6-11中name屬性的默認值為“bill”。
對於索引屬性的類型來說,可以是數組,也可以是java.util.List接口的類(如ArrayList)。我們還可以為動態Form的屬性指定實現java.util.Map接口的類作為數據類型(也就是映射屬性)。但遺憾的是,如果使用動態Form,就無法使用泛型進行自動類型轉換了。
四、訪問動態Form
我們可以使用DynaActionForm類的getter方法來讀取動態Form中的屬性值。DynaActionForm類的getter方法有三個重載形式,分別用來讀取簡單屬性、索引屬性和映射屬性。這三個getter方法的定義如下:
public Object get(String name) ; // 讀取簡單屬性
public Object get(String name, int index) ; // 讀取索引屬性
public Object get(String name, String key); // 讀取映射屬性
下面的代碼演示了如何通過getter方法獲得動態Form的屬性值:
DynaActionForm dForm = (DynaActionForm)form;
String name = (String)dForm.get("name");
String[] hobbies = (String[])dForm.get(“hobbies”);
String value1 = (String)dForm.get(“myMap”, “key1”);
除了上述的get方法外,DynaActionForm還提供了getString和getString方法,分別用來讀取String和String[]類型的屬性值,這兩個方法的定義如下:
public String getString(String name) ;
public String[] getStrings(String name) ;
下面的代碼演示了如何通過getString和getStrings方法獲得動態Form的屬性值:
String name = dForm.getString(“name”); // 相當於String name = (String)dForm.get("name");
String[] hobbies = dForm.getStrings(“hobbies”); // 相當於String[] hobbies = (String[])dForm.get(“hobbies”);
在使用getString和getStrings方法時應注意,這兩個方法只能讀取String或String[]類型的屬性,讀取其他類型的屬性將會拋出異常。
五、一個動態Form的例子
我們在這一部分來實現一個完整的動態Form的例子,在這個例子中的動態Form有四個屬性,三個是簡單數據類型,一個是數組類型。完成這個例子需要如下四步:
【第1步】配置動態Form
打開struts-config.xml,在<form-beans>元素中加入如下的內容:
<form-bean name="dynamicForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="name" type="java.lang.String" />
<form-property name="age" type="java.lang.Short" />
<form-property name="salary" type="java.lang.Float" />
<form-property name="hobby" type="java.lang.String[]" />
</form-bean>
【第2步】編寫Struts Action類
這個Struts Action類負責從動態Form中獲得屬性值,並輸出到客戶端浏覽器。在<samples工程目錄>"src"action目錄中建立一個DynamicAction.java文件,代碼如下:
package chapter6.action;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.io.*;
public class DynamicAction extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
{
try
{
DynaActionForm dForm = (DynaActionForm) form;
String name = (String) dForm.get("name");
Short age = (Short) dForm.get("age");
Float salary = (Float) dForm.get("salary");
// 獲得數組類型字段值的數組長度
int hobbyCount = ((String[]) dForm.get("hobby")).length;
PrintWriter out = response.getWriter();
out.println("name: " + name + "<p/>");
out.println("age: " + age + "<p/>");
out.println("salary: " + salary + "<p/>");
for (int i = 0; i < hobbyCount; i++)
out.println("hobby" + (i + 1) + ": " + dForm.get("hobby", i) + "<p/>");
}
catch (Exception e)
{
}
return null;
}
}
【第3步】配置Struts Action
打開struts-config.xml文件,在<action-mappings>元素中加入如下的內容:
<action name="dynamicForm" path="/dynamic" scope="request" type="action.DynamicAction" />
【第4步】編寫用戶錄入數據的JSP頁面
在Web根目錄中建立一個dynamic.jsp文件,代碼如下:
<%@ page pageEncoding="GBK"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>測試動態Form</title>
<html:base/>
</head>
<body>
<html:form action="dynamic" >
姓 名:<html:text property="name" /> <p>
年 齡:<html:text property="age" /> <p>
工 資:<html:text property="salary" /> <p>
愛好1:<html:text property="hobby" value=""/> <p>
愛好2:<html:text property="hobby" value=""/> <p>
愛好3:<html:text property="hobby" value=""/> <p>
<html:submit value="提交" />
</html:form>
</body>
</html>
啟動Tomcat後,在IE中輸入如下的URL來測試程序:
http://localhost:8080/samples/dynamic.jsp
六、驗證動態Form
有兩種方法可以驗證動態Form:
1.在DynaActionForm的子類中覆蓋validate方法。
2.如果要使用Validator框架來驗證動態Form,需要用DynaActionForm的子類org.apache.struts.validator. DynaValidatorForm或其子類來作為動態Form的類型。
在使用DynaValidatorForm的了類時,要想使用Validator框架的驗證機制,需要在DynaValidatorForm子類的validate方法的開始位置使用 super.validate()語句來調用DynaValidatorForm中的validate方法。