1. 程式人生 > >Struts 的動態複選框

Struts 的動態複選框

級別: 中級

2005 年 11 月 28 日

Struts Recipes 的合著者 Danilo Gurovich 從 George Franciscus 停止的地方開始,介紹了易於使用的建立動態選擇複選框的 Struts 訣竅。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

在使用者介面設計中,複選框組不如它的同類 —— 多行選擇框那樣流行。它們基本上做的是同一件事,即選擇對映到單一 name

屬性的一組選項。當在組中使用時,複選框執行的功能實際與多行選擇框一樣,但是它們佔據的螢幕空間更多。當希望使用者在選擇一個或多個選項之前能夠看到所有選項的時候,這會很有好處。

雖然在選項不多的時候,多行選擇框通常提供更好的觀感,但是當選擇框必須動態呈現而且包含預選功能時,對企業應用程式來說複選框組會是更好的選擇。幸運的是,使用 Struts 框架可以很容易地建立動態複選框組。

在這篇文章中,我將介紹一個簡單的訣竅:用 Struts 的 <html:multibox/><logic:iterate/> 標記在應用程式的檢視層呈現大量條目,在本例中是 Java™ Server Page(JSP)。

我先從使用複選框元素顯示簡單的 String[] 陣列開始,陣列中包含喜瑪拉雅山的頂峰高度。然後,我將建立另外一個 String[] 陣列,包含 selectedMountains ,代表已經選中的複選框。複選框的預選情況會在兩個陣列的交叉中產生。如果 selectedMountains 的初始陣列為空,那麼所有複選框最初都會顯示為未選中。

請參閱 下載 獲得完整的示例原始碼。應當擁有跟隨本文所需要的每樣東西。如果需要下載 Struts 框架,請參閱 參考資料

建立動態複選框的訣竅包含三個主要部分:

  • 一個表單 bean,容納複選框的 String[] 陣列和表示選中複選框的 String[] 陣列。

  • 一個 JSP,帶有一個表單,在需要的時候顯示覆選框。

  • 一個簡單的 Action 類,從表單頁面轉到顯示頁面。

請注意 “Himalayas” 示例非常簡單。用來填充複選框的欄位應當來自更復雜的模型,比如這樣的模型,它能夠標識使用者,並選擇要顯示的欄位,然後把業務物件認為需要的選項預先選中。我採用簡單的模型是為了更好地演示 Struts 的使用者介面功能。程式碼示例使用 JSP 指令碼語言是為了表示清楚。





回頁首


我先從建立 Struts 表單 bean 開始,它包含填充複選框所需要的資訊。請注意清單 1 中的 TestForm.java 包含了兩個示例 String[] 陣列變數的 getter 和 setter。陣列 mountains 代表示例複選框的 全部選項,陣列 selectedMountains 代表預選的在瀏覽器中顯示為選中的元素。

除了代表初始選中的複選框,selectedMountains 還代表處理表單時,由使用者選中的複選框。(它只代表最終選中的元素。)當請求頁面時,會顯示覆選框。當我在它們之間迭代時,與 selectedMountains 匹配的複選框元素就是選中的元素。

清單 1 顯示了 TestForm.java 的完整程式碼:


清單 1. TestForm.java
				
package com.strutsrecipes;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
public final class CheckboxTestForm
extends ActionForm {
// Instance Variables
/*Mountains "pre-selected"...*/
private String[]
selectedMountains
=
{"Everest","K2","Lhotse"};
/*the ten tallest Mountains to iterate through*/
private String[]
mountains
=
{"Everest","K2","Kangchenjunga","Lhotse",
"Makalu","Kangchenjunga South",
"Lhotse Middle","Kangchenjunga West",
"Lhotse Shar","Cho Oyu"};
/*Getter for selectedMountains*/
public String[] getSelectedMountains() {
return this.selectedMountains;
}
/*Setter for selectedMountains*/
public void setSelectedMountains(String[] selectedMountains) {
this.selectedMountains = selectedMountains;
}
/*Getter for the mountains*/
public String[] getMountains() {
return this.mountains;
}
/*Setter for the mountains*/
public void setMountains(String[] mountains) {
this.mountains = mountains;
}
}





回頁首


接下來,我要編寫頁面的 JSP 程式碼,把 TestForm.java 的資訊傳遞給檢視層。在編寫這個程式碼時,關鍵是要把對應的 Struts 標記庫匯入 JSP。清單 2 的 JSP 程式碼表示的是一個簡單的表單,顯示覆選框中相應的框已經選中:


清單 2. 帶有表單的 JSP
				
<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
<%-- html code, etc... -->
<html:form
action="/FormAction" 
name="testForm"
type="com.strutsrecipes.CheckboxTestForm">
<h4><bean:message key="testForm.instruction"/></h4>
<logic:iterate name="testForm" 
property="mountains" 
id="mountain">
<%-- create the checkbox and selected attribute -->
<html:multibox property="selectedMountains">
<bean:write name="mountain"/>
</html:multibox>
<%-- create the label, note that "br" tag will format it vertically -->
<bean:write name="mountain"/><br/>
</logic:iterate>
<br/>
<html:submit/><html:reset/>
</html:form>
<%-- some more html code, etc... -->

注意,我用 Struts <bean:message/> 標記表示文字,用 <html:multibox/> 表示 HTML 複選框,用 <logic:iterate/> 標記在陣列中迭代並建立相應內容。我的表單在 JSP 中通過 <html:form/> 標記被例項化。

下一步是對 <logic:iterate/> 標記中的 mountains 欄位進行迭代。在這麼做的時候,我建立了一個變數(mountain),用它來填充複選框,並用 <bean:write/> 標記給它一個標籤。要在複選框中建立 selected 屬性,我要再次使用 <logic:iterate/><html:multibox/> 標記。<html:multibox/> 標記中的 property 屬性由 selectedMountains 欄位填充。當 selectedMountains 等於 mountain 時,selectBox 就是選中的。





回頁首


最後一步是編寫 Action 類。清單 3 比起其他清單,做的事並不多。我做的只是得到 selectedMountainsString[] 陣列,並使它可以用於頁面:


清單 3. 表單的 Action
				
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* A simple Action for Checkbox test.
*
* @author Danilo Gurovich
*/
public final class CheckboxTestAction
extends Action {
// -------------------------- OTHER METHODS --------------------------
/**
* The execute method
*
* @param mapping ActionMapping
* @param form CheckboxTestForm
* @param request HttpServletRequest
* @param response HttpServletRespons
* @return success to the confirmation page
* @throws ServletException not thrown, but could be!
* @throws Exception ditto.
*/
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, Exception {
// Extract attributes needed
String[] selectedMountains =
((CheckboxTestForm) form).getSelectedMountains()
;
System.out.println("htmlString RETURNED*\n" +
selectedMountains.toString());
//Save the htmlString in the session for later...
HttpSession session = request.getSession();
session.setAttribute(CheckboxConstants.MOUNTAINS, selectedMountains);
return (mapping.findForward("success"));
}
}





回頁首


有了這個程式碼,工作就完成了,差不多可以展示成果了!使用者現在可以提交 JSP 表單並在 Action 類引用的對應頁面中檢視結果。清單 4 中的程式碼段顯示了使用者在簡單 JSP 頁面的表單中選中的複選框列表:


清單 4. 複選框選擇的結果
				
<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
<%-- html code, etc... -->
<logic:iterate id="mountain" property="mountains" name="testForm">
<bean:write name="mountain"/><br/>
</logic:iterate>
<hr size=5 color="black"/>
<%-- some more html code, etc... -->





回頁首


這個訣竅的關鍵是表單 bean 中的欄位被傳遞到頁面。檢視相關 JSP 程式碼有助於澄清這點。一旦表單 bean 被例項化:

<html:form action="/FormAction" 
name="testForm"
type=" com.strutsrecipes.CheckboxTestForm">

下一步為 Java 類的 mountains 變數中的每個 mountain 建立一個複選框。要做到這一點,我必須像下面這樣在 String[] 陣列中迭代:

<logic:iterate id="mountain"
property="mountains" 
name="testForm">

使用 <logic:iterate> 標記,我呼叫了 testForm bean 中的 getMountains() 方法。它在這個陣列中迭代,並把每個值作為已經命名的 pageContext() 級的 String mountain[] 陣列變數返回(即 id="mountain")。

在這裡可以看到 <html:multibox/> 標記的效果以及如何顯示它:

<html:multibox property="selectedMountains">
<bean:write name="mountain"/>
</html:multibox>
<bean:write name="mountain"/><br/>

注意 property 屬性被 selectedMountains 填充,這是我選中的變數。當這個變數與 <html:multibox/> 值(即 multibox 標記中的 <bean:write/>)對應時,在呈現表單的時候它就表現為選中。如果使用者選中表單或取消選中,那麼新的 selectedMountains 值就被髮送給 Action 類進行處理。這個迭代中的第二個 <bean:write/> 標記建立該標記使用的標籤,後面跟著 <br/> 標記,讓檢視在一長列中顯示這些標記。





回頁首


通過使用 Struts LabelValueBean 類代替簡單的 String[] 陣列,可以對動態複選框這個訣竅進行擴充套件,從而為複選框建立不同的標籤。先從新增 LabelValueBeansjava.util.List 開始。然後對列表進行迭代,把 LabelValueBeans 標籤和值釋放到適當的位置。這個略微複雜的訣竅與動態複選框訣竅的效果相同,但是它的結果更適合實際的使用者介面設計。清單 5 顯示了擴充套件的動態複選框訣竅:


清單 5. 新增標籤到動態複選框
				
<logic:iterate id="mountainlb" 
property="mountainslb" 
name="testForm">
<bean:define id="mountainbean" 
name="mountainlb
"type="org.apache.struts.util.LabelValueBean"/>
<html:multibox property="selectedMountains">
<bean:write name="mountainbean" 
property="value"/>
</html:multibox>
<bean:write name="mountainbean" 
property="label"/><br/>
</logic:iterate>

注意,這裡大的變化是用 <bean:define/> 在迭代的時候建立 LabelValueBean。然後用 <bean:write/> 輸出每個 mountainbean 的屬性(即 org.apache.struts.util.LabelValueBean 類的 getLabel()getValue() 方法)。





回頁首


結束語

Struts 對於複選框的動態呈現和預選提供了優秀的支援。這個訣竅是我合著 Struts Recipes 的原因 —— 那時我已經發現許多與 Struts 框架相關的理論和伺服器端資訊,但是使用者介面程式設計多數被忽略了,或者被掩蓋了。在上上下下找了一圈使用 Struts 建立複選框的訣竅之後,我放棄了,並自己寫了一個。通過把不同的部分組合起來,我可以建立適合我的動態複選框系統。

您會注意到,程式碼示例被設定為適合用作不同使用者介面小控制元件和佈局想法的測試溫床。實際上,我在書中的大多數使用者介面示例中都使用了它,只需要調整 Action 類和我的模型去適合訣竅的需求而已。我還把它用在測試不同的想法上,這樣就不用在我正在處理的應用程式內部花太多時間為某些東西編碼了。






回頁首


下載

描述 名字 大小 下載方法
Sample code j-sr3-source.zip 3249 KB HTTP


參考資料

學習
  • 您可以參閱本文在 developerWorks 全球站點上的 英文原文

  • Struts 與 Velocity 的整合”(George Franciscus,developerWorks,2005 年 9 月):Velocity 模板引擎是 Struts 中 Java 伺服器頁面的一個快速而靈活的替代。

  • 整合 Struts、Tiles 和 JavaServer Faces”(Srikanth Shenoy 和 Nithin Mallya,developerWorks,2003 年 9 月):利用 JavaServer Faces 的前端威力、Tiles 的格式化力量以及 Struts 控制器層的靈活性。

  • Struts Recipes(George Franciscus 和 Danilo Gurovich;Manning,2004):Struts 訣竅和最佳實踐的一份流行的概要。

  • Struts In Action(Ted Husted、Cedric Dumoulin、George Franciscus、David Winterfeldt;Manning,2002):面向專業 Struts 開發人員的豐富資源。

  • Java 技術專區:找到 Java 程式設計各方面的文章。


獲得產品和技術
  • Struts 主頁:包含 Struts 頁面構建標記的完整清單。


討論


關於作者

Danilo Gurovich 是一位應用程式架構師,曾經為高流量的商業、EAI 監視和控制以及業務流程管理設計和實現了基於 Struts 的應用程式。他與 George Franciscus 合著了 Struts Recipes 一書。