【原創】Struts1.x系列教程(14):動態Form

銀河使者發表於2009-03-02

本文為原創,如需轉載,請註明作者和出處,謝謝!

一、動態Form簡介

    雖然ActionForm功能強大,但有些時候使用起來有些麻煩。如每建立一個使用者錄入介面(JSP頁面),就得建立一個ActionForm子類來和這個頁面對應。當然,我們可以採用巢狀屬性從一定程度上彌補這個問題。但是在建立新的使用者錄入介面時,仍不可避免地要建立新的ActionForm子類。

    Struts1.2.6及以後的Struts版本中提供了一種動態Form的技術。使得不用再建立新的ActionForm就可以封裝使用者提交的資料。實際上,這種技術將定義ActionForm子類的工作變成了編寫XML檔案的工作。

    每定義一個動態Form,就要在struts-config.xml中加一個元素,並使用子元素來定義動態Form的屬性。

    在本章的最後還會介紹一個LazyValidatorForm類,通過這個類甚至可以不定義動態Form的屬性就可以使用動態Form。這將大大簡化開發人員的工作量。    

二、宣告動態Form 

    宣告一個動態Form非常簡單,只需要在struts- config.xml的元素中加入一個子元素,並使用元素來定義動態Form的屬性。我們可以定義的屬性型別有簡單屬性(如String)、索引屬性(如陣列)、對映屬性(如 HashMap)以及巢狀屬性(屬性型別是另一個類)。
    對於動態Form來說,Form的型別必須是org.apache.struts.action.DynaActionForm或其子類。宣告一個動態Form的程式碼如下:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt <form-bean name="dynamicForm"  type="org.apache.struts.action.DynaActionForm">
    <!-- 宣告一個簡單屬性 --&gt
    <form-property name="simpleProp" type="java.lang.String" initial="bill"/>
    <!-- 宣告一個索引屬性 --&gt
    <form-property name="indexedProp" type="java.lang.String[]" />
    <!-- 宣告一個對映屬性 --&gt
    <form-property name="mappedProp" type="java.util.HashMap" />
    <!-- 宣告一個巢狀屬性 --&gt
    <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中代表的資料型別是完全一樣的。我們還可以使用元素的initial屬性為動態Form的簡單屬性指定一個預設值。如在例程6-11name屬性的預設值為“bill”。

對於索引屬性的型別來說,可以是陣列,也可以是java.util.List介面的類(如ArrayList)。我們還可以為動態Form的屬性指定實現java.util.Map介面的類作為資料型別(也就是對映屬性)。但遺憾的是,如果使用動態Form,就無法使用泛型進行自動型別轉換了。

四、訪問動態Form

    我們可以使用DynaActionForm類的getter方法來讀取動態Form中的屬性值。DynaActionForm類的getter方法有三個過載形式,分別用來讀取簡單屬性、索引屬性和對映屬性。這三個getter方法的定義如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  public Object get(String name) ;   // 讀取簡單屬性
  public Object get(String name, int index) ;  // 讀取索引屬性
  public Object get(String name, String key);  // 讀取對映屬性
   
    下面的程式碼演示瞭如何通過getter方法獲得動態Form的屬性值:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtDynaActionForm dForm = (DynaActionForm)form;
String name 
= (String)dForm.get("name");
String[] hobbies 
= (String[])dForm.get(“hobbies”);
String value1 
= (String)dForm.get(“myMap”, “key1”);

    除了上述的get方法外,DynaActionForm還提供了getStringgetString方法,分別用來讀取StringString[]型別的屬性值,這兩個方法的定義如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtpublic String getString(String name) ;  
public String[] getStrings(String name) ;

    下面的程式碼演示瞭如何通過getStringgetStrings方法獲得動態Form的屬性值:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtString name = dForm.getString(“name”);  // 相當於String name = (String)dForm.get("name");
String[] hobbies = dForm.getStrings(“hobbies”);  // 相當於String[] hobbies = (String[])dForm.get(“hobbies”);

    在使用getStringgetStrings方法時應注意,這兩個方法只能讀取StringString[]型別的屬性,讀取其他型別的屬性將會丟擲異常。  

五、一個動態Form的例子

    我們在這一部分來實現一個完整的動態Form的例子,在這個例子中的動態Form有四個屬性,三個是簡單資料型別,一個是陣列型別。完成這個例子需要如下四步:

【第1步】配置動態Form.
    開啟struts-config.xml,在元素中加入如下的內容:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt<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中獲得屬性值,並輸出到客戶端瀏覽器。在工程目錄>"src"action目錄中建立一個DynamicAction.java檔案,程式碼如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  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 + "

");
              out.println(
"age: " + age + "

");
              out.println(
"salary: " + salary + "

");
              
for (int i = 0; i < hobbyCount; i++)
                  out.println(
"hobby" + (i + 1+ "" + dForm.get("hobby", i) + "

");
          }
          
catch (Exception e)
          {
          }
          
return null;
      }
  }

【第3步】配置Struts Action     

    開啟struts-config.xml檔案,在元素中加入如下的內容:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  <action name="dynamicForm" path="/dynamic" scope="request" type="action.DynamicAction" />

【第
4步】
編寫使用者錄入資料的JSP頁面

    在Web根目錄中建立一個dynamic.jsp檔案,程式碼如下:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt  @ page pageEncoding="GBK"%>
  
@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
  
<html>
    
<head>
      
<title>測試動態Formtitle>
      
<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方法

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12921506/viewspace-558306/,如需轉載,請註明出處,否則將追究法律責任。

相關文章