Struts 和 Tiles 輔助基於組件的開發

- 中國WEB開發者網絡 (http://www.webasp.net)
-- 技術教程 (http://www.webasp.net/article/)
--- Struts 和 Tiles 輔助基於組件的開發 (http://www.webasp.net/article/19/18068.htm)
-- 作者:未知
-- 發佈日期: 2005-04-28
將視圖組合在一起以便於構造 Web 應用程序
級別:中級


Wellie Chao(wchao@caraveltech.com)
總裁,Caravel Technologies
2002 年 8 月

「模型-視圖-控制器(Model-View-Controller,MVC)」框架對於生成有組織的模塊化應用程序(這些應用程序能夠清晰地劃分邏輯、樣式和數據),是一種經證實的和方便的方法。在 Java 世界中,Struts 是最著名的也是最常被談及的 MVC 的開放源碼體現之一。致力於 Struts 的開發人員最近增強了該項目的核心功能,並改進了視圖支持(合併了 Tiles 視圖組件框架來加強對基於組件開發的支持),以便增加可重用性並增強一致性。本文中,Wellie Chao 說明了 Struts 和 Tiles 組合為什麼是用來創建 Web 應用程序的最佳工具包,而且向您展示了如何開始使用它,這裡主要講述自 Struts 0.9 以來的更改。
我開始學習如何創建軟件要追溯到 80 年代中期,最初兩個月的時間都花在使用線性流及嵌入式顯示、邏輯和數據編寫單塊代碼。這在那時,好像是最常用的方法。隨著經驗的豐富,我學會了將代碼封裝到對像中,將數據與邏輯分離,重構公共代碼並實踐其它良好的編程公認原則。

Web 開發人員接受 MVC
眨眼到了 1994 年,當時主流的採用 Web 應用程序的開發才剛開始。由於 Web 的不成熟,只有較少的工具能幫助開發人員構建 Web 軟件。結果,在特定解決方案中的應用程序混合了 HTML 代碼與應用程序邏輯。很顯然,UI 設計的更改和業務邏輯的更新在大型應用程序中既困難又昂貴,因為緊耦合的表示和邏輯將這兩種元素攪和在一起,進而導致錯誤和緩慢的進展。而且,混合的代碼要求部分開發人員具備 UI 設計知識,或者要求開發人員與圖形設計人員之間有緊密的工作關係,這常常會造成時間上的浪費。

JSP 技術和標記的引入稍微改善了這種更改問題,因為能夠將邏輯和顯示分離。UI 設計人員能夠對顯示進行卓有成效的工作,同時開發人員能夠專注於邏輯。然而,這種方法仍存在一些缺陷。尤其是某些操作(還有公共操作)的開發仍很困難。驗證表單就是典型的例子。正如很多人所知,表單驗證的過程類似於這樣:

顯示表單;等待用戶填寫然後提交數據。 
檢查各域值是否有效;如果有錯誤,則重新顯示表單。 
處理用戶輸入的數據,可能將其存儲在一個數據庫中。 
在新頁面上向用戶顯示處理的結果或下一步(可能是另一個表單)。 
如果在這一過程中只使用 JSP 頁面,那麼在需要再次更改代碼時,您會發現,按照可管理性這條思路,將控制從一個頁面「路由」至另一個頁面很難。您想把第 4 步和第 3 步置於同一個頁面嗎?如果使用多個單獨的 JSP 頁面,那麼如何跟蹤哪個頁面鏈接至其它頁面,以及在要更改一個頁面的文件名或位置時該怎麼做呢?而且,在第 2 步檢測到某個域中的錯誤時,如何重新顯示帶有一條錯誤消息的原始表單,但還要保留用戶已填入的值呢?Struts,一種開放源碼「模型-視圖-控制器」框架,通過幫助解決所有這些問題,從而使開發人員的工作更為輕鬆。

本文並不深入討論 MVC 平台。有關這方面的信息,請參閱 Malcolm Davis 所寫的標題為「Struts, an open-source MVC implementation」的 developerWorks 文章。您正在閱讀的這篇文章討論自 Malcolm 的文章發表以來對 Struts 所做的更改,包括 Tiles 庫。至於代碼的安裝過程,本文僅涉及 Jakarta Tomcat 4.0(Catalina)最小安裝所需的步驟。如果您沒有使用 Tomcat,請查閱手冊以瞭解您的應用程序服務器。

Struts 和 Tiles 的背景知識
Craig McClanahan 是 Apache Tomcat 項目的技術主管,他創立 Struts 項目以滿足對這方面的渴望。它作為「模型-視圖-控制器」框架首選的並經過正式認可的開放源碼實現,已經越來越流行了。它以與交付產品一起分發的形式受到來自 Sun 和 IBM 的支持。因為 Craig 積極參與 Tomcat 和 Struts 的開發工作,所以 Struts 將繼續與 JSP 和 Servlet 規範的參考實現高度兼容,進而與所有 J2EE 應用程序服務器高度兼容。

Malcolm Davis 的有關 Struts 的 developerWorks 文章涵蓋了整個 Struts 0.9 的功能;為了簡短起見,我將只討論對 Struts 0.9 的更改以及他未涉及的 Struts 主題。目前的 Struts 發行版本是 1.0.2,但自 2002 年 3 月 19 日起有一個標記為 1.1-b1 的 beta 測試版可供使用。因為 beta 測試版表示編碼工作已經完成,在這種情況下只進行錯誤修正,所以極有可能 1.1 的最終版本不久就將面市,而在 Struts 郵件列表上已經有這種呼聲。因此,任何利用 Struts 的新項目很可能都將 1.1 代碼作為基礎,而這就是我將討論的內容。

自版本 0.9 以來對 Struts 框架的有用添加包括經改進的表單驗證功能、可以通過 XML 聲明來指定表單元素和可以動態地定義 bean 特性。然而,最重要的添加可能是將 Tiles 模板庫合併到 Struts 分發版中。

您是否曾希望用一種更簡便的方法創建一組頁面(或可能是整個應用程序),並且每個頁面上的用戶界面保持一致 ? 有相同的導航欄、頁眉和頁腳等等?在含有較多內容的頁面內顯示多個類 portlet 的矩形內容的方法又如何?在 Tiles 框架的幫助下,您可以完成這兩項任務和其它更多任務。通過定義屏幕和一組可嵌入在 JSP 頁面中的標記的核心 XML 文件來插入靜態和動態內容,Tiles 框架允許您構建組件化的視圖,並按您的希望來組裝它們,從而有助於提高靈活性、可重用性、一致性和可維護性。

Struts 和 Tiles 之間交互良好,因為這兩個項目的開發人員已經認識到這兩者具有互補性,所以決定讓這兩者共同協作。開發人員可以指定 Tiles 頁面定義作為 Struts 操作的目標視圖(按照 Struts 的說法是一個 forward)。因為 Struts 和 Tiles 都遵循 JSP 標記庫規範,所以可以在 JSP 頁面中將 Struts 標記和 Tiles 標記相互混合在一起。

您可能渴望嘗試 Tiles 框架,並確切地瞭解它可以做些什麼。如果您希望在自己安裝本文的示例前先瞭解這些示例的運行情況,可以看看它們在帶有嵌入式 Tomcat 的 JBoss 服務器上是怎樣運行的。

Struts 和 Tiles 是用於 Web 開發的輔助工具,所以您需要設置一個 Web 容器對它們進行實驗;將 Tomcat 設置為您的容器,然後設置 Struts 和 Tiles 包,我會在下一節中循序漸進地講述這一過程。這些指導信息還向您展示了如何安裝本文的樣本代碼。一旦完成了這一切,您就準備好繼續本文。示例 1 應用程序沒有利用 Struts 和 Tiles;它演示了以頁面為中心的方法。通過將它與示例 2 比較,您會看到 Struts 和 Tiles 將如何極大地提高您的 Web 開發的結構化程度和可管理性。最後,示例 3 演示了將功能添加到一個使用 Struts 和 Tiles 的、並且已經啟動且正在運行的 Web 應用程序中是多麼地簡單。

安裝 Struts 和 Tiles
在帶有 J2SE 1.4 SDK、Ant 1.4.1、Tomcat 4.0.3 和 Struts 1.1-b1 的 Linux 機器上,下列指導信息已經經過了測試。如果因這些軟件包的版本不同而遇到困難,您可能需要使用上面所指定的版本,以便開始瞭解 Struts 和 Tiles 的設置和開發。

如果您沒有 J2SE 1.4 SDK(Java 2 Platfrom,標準版 1.4 軟件開發工具箱),請從 http://java.sun.com/j2se/1.4/download.html 獲取它,然後遵循該軟件包中的指導信息來安裝它。您需要 SDK 而不只是 JRE,但是您可以選擇獲取 Forte/SDK 組合。


確保您的環境變量 JAVA_HOME 設置為 J2SE 1.4 SDK 的安裝目錄。


如果沒有 Ant 1.4,請從 http://jakarta.apache.org/builds/jakarta-ant/release/v1.4.1/bin/ 獲取二進制分發版,然後將它解壓縮。對於 Ant 1.4 以及安裝指導信息中所要求的所有其它包,請確保獲取的都是二進制分發版,而不是源代碼;否則,您將不得不在使用它們之前編譯這些包。同樣,將 Ant 的 bin 目錄添加到您的路徑中。


請從 http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.0.3/bin/ 獲取 Tomcat 4.0.3 二進制分發版,然後將它解壓縮。文件名應該與 jakarta-tomcat-4.0.3-LE-jdk14.tar.gz 相似。為了便於稍後在這些指導信息中引用此名稱,讓我們暫且任意地將安裝目錄(至並且包括 Tomcat 目錄)的路徑稱為 TOMCAT_HOME。在 UNIX 系統上,該路徑類似於 /home/wchao/jakarta-tomcat-4.0.3-LE-jdk14,在 Windows 系統上類似於 c:jakarta-tomcat-4.0.3-LE-jdk14。


請從 http://jakarta.apache.org/builds/jakarta-struts/release/v1.1-b1/ 獲取 Struts 1.1-b1 beta 測試發行版,然後將它解壓縮(不在 TOMCAT_HOME 中)。我們稱該目錄為 STRUTS_INSTALL。在 UNIX 系統上,該目錄類似於 /home/wchao/jakarta-struts-1.1-b1,在 Windows 系統上類似於 c:jakarta-struts-1.1-b1。


請下載 struts-tiles-examples.tgz,然後將它解壓縮。它將創建三個目錄:ex1、ex2 和 ex3。我們分別稱這些目錄為 EX1_INSTALL、EX2_INSTALL 和 EX3_INSTALL。


轉至 TOMCAT_HOME/bin 目錄。


通過輸入 ./startup.sh(如果在運行 UNIX)或 ./startup.bat(如果在運行 Windows)來啟動 Tomcat 服務器。


將 Web 瀏覽器指向 http://localhost:8080/examples 來驗證 Tomcat 是否已啟動並正確運行。缺省情況下,Tomcat 附帶了 Examples 應用程序。如果 Examples 不工作,則 Tomcat 發生故障;請參閱 Tomcat 文檔來解決問題。 
Hello, World:首次嘗試
要研究我們第一個示例,請遵循下列步驟:

轉至 EX1_INSTALL 目錄。


編輯 build.xml 文件,為 tomcat.install.dir 填寫適當值。儘管該值可以是絕對路徑,也可以是相對路徑;但如果您不瞭解 Ant 是如何工作的,或許最好使用絕對路徑。


輸入 ant deploy。這將把第一個示例應用程序構建到 WAR 文件中,以備部署,然後將它部署至 Tomcat。如果得到一個指出無法找到 Ant 的錯誤,請參閱「安裝 Struts 和 Tiles」一節中的第 3 步,並確保您的路徑環境變量包含 Ant。


將 Web 瀏覽器指向 http://localhost:8080/ex1。您應該會看到「Hello, World」頁面。 
示例 1 Web 應用程序非常簡單,它演示了常見的 Web 應用程序功能。幾乎所有應用程序(也包括這個最簡單的應用程序)都要求所有頁面具有一致的用戶界面。通常,這意味著所有頁面都有公共的徽標、頂部欄、上部或左側導航欄、主體和頁腳。在示例 1 中,我有意對每一頁面中的公共項進行硬編碼,以便說明這一點。Web 應用程序開發的新手一般會通過將現有代碼複製粘貼到新文檔中來添加新的功能頁面。很容易預見這種方法難以應付將來的變化。隨著每一次增加新內容,更改諸如菜單、徽標等公共頁面元素的過程花的時間會更長,更容易出錯。很明顯,複製粘貼方法對於任何具有大量頁面的應用程序是一個糟糕的模型。

敏銳的讀者會認識到 JSP 技術提供了包括來自其它 servlet 和頁面中的內容的功能。我們為什麼不可以僅僅使用 <jsp:include/> 標記來合併公共元素呢?這肯定會使那些元素更易於更改。如果您需要更改菜單,只要更改包含菜單的文件。所有其它頁面只需使用 <jsp:include/> 標記就可以得到菜單中的內容,這樣這些頁面可以自動獲得對菜單的更改。但是,當需要更改實際佈局或需要重新組織文件和目錄時,這種方法有不足之處。當決定更改以頁面為中心模型下的佈局時,必須對每個單個頁面進行更改,因為即使對公共元素的訪問已做了集中化處理,但仍然是由每個頁面中的 HTML 代碼來描述佈局本身(有哪些是元素及它們的位置)。同樣地,當決定更改包含了某個公共元素內容的文件的文件名或位置時,必須逐個更改使用該元素的文件。什麼原因呢?因為每個文件根據固定的物理文件名,而不是邏輯對像名來查找每個公共元素。因此,必須更新每個對物理文件名的引用。Tiles 視圖組件可以解決這些問題。

如果更進一步地研究 index.jsp 和 form1.jsp(這兩個 JSP 文件構成該應用程序),會發現另一個缺點:錯誤處理相當笨拙。錯誤處理代碼是在 form1.jsp 中,其中我必須重複顯示代碼,並添加代碼以插入用戶在前一表單屏幕(index.jsp)中輸入的值。如果用戶概要信息域曾更改過,或者如果輸入表單的顯示曾更改過,就必須更新這兩個地方中的代碼。我可以將 form1.jsp 的錯誤處理部分與 index.jsp 中的初始表單顯示結合在一起,但在初始表單裝入時,我仍將需要做額外的工作以把域值設置成空字符串,並且我仍將需要有一個物理文件名來表示用戶概要信息的最終靜態顯示,這意味著發生更改時,該應用程序結構仍是很脆弱的。Struts 表單自動化可以解決這種笨拙的表單處理缺陷。

下表 1 總結了由示例 1 應用程序演示的基於 JSP、以頁面為中心的 Web 應用程序模型的優缺點。

表 1. 基於 JSP 方法的概述 

優點 說明 
入門容易。 只要設置 Tomcat,然後就可以開始編寫代碼。不需用核心文件來保持同步,也不需要冗長的庫初始配置。由每個單獨的 JSP 頁面或 servlet 來指定連接。 
缺點 說明 
在應用程序的不同部分中重用表示很困難。 一定程度上,可以使用 <jsp:include/> 標記來解決一部分重用,但它們在管理更改方面不能很好地工作。 
公共輸入和數據處理任務枯燥且重複。 錯誤處理是普通 JSP 頁面的常見問題。而且,必須手工填入表單值及手工檢索請求對像中的那些值,這是一件既耗時又枯燥的工作。 
業務邏輯和表示緊密耦合在一起,從而將兩者的代碼混合在一起。 如果研究一下 index.jsp 和 form1.jsp,就會發現 Java 代碼是與 HTML 代碼混在一起的。代碼很難看,易於出錯,而且要做到使 Java 編碼或用戶界面開發分離開非常困難。最終不得不同時瞭解 HTML 和 Java 編碼對頁面的作用。 
沒有對應用程序流或行為的集中描述。 除非逐個查看頁面,否則根本無法瞭解應用程序的整體印象以及操作流是怎樣運作的。隨著項目越來越大,容易造成錯誤、失敗和令人迷惑的地方。 

Hello, World:經改進的新的應用程序
現在,讓我們研究剛才看到的 Web 應用程序示例中的 Struts 和 Tiles 版本。請執行下列步驟:

轉至 EX2_INSTALL 目錄。


編輯 build.xml 文件,為 struts.install.dir 和 tomcat.install.dir 填寫適當的值。


輸入 ant deploy。這將把第二個示例應用程序構建到 WAR 文件中以備部署,然後將它部署至 Tomcat。如果看到關於無法複製文件的錯誤,請檢查第 2 步以確保正確設置了 struts.install.dir 和 tomcat.install.dir。


將 Web 瀏覽器指向 http://localhost:8080/ex2。您應該會看到「Hello, World」頁面。 
目錄結構和文件的說明
在 EX2_INSTALL/src/web 目錄下有不少文件,乍看起來可能會把人搞糊塗。以下是給大家的一些指導。 
profileInput.jsp 和 profileOutput.jsp 頁面是頁面主體 panel3 的內容;它們驅動這一特殊應用程序。在 tiles-components 下有頁面的各種組件,而在 tiles-layouts 下是有關佈局的 HTML 代碼。我喜歡這樣的組織安排,因為這使得對不同的用戶角色有不同的佈局,並在一個中心位置中保存所有視圖組件。Tiles 可以讓您以您希望的任何方式安排文件,只要您在 tiles-defs.xml 文件中指定了如何組織事物,所以使用那些最適合於您工作的事物。

如果您已看過 EX2_INSTALL 目錄,您很可能會說:「這裡要做些什麼呢?有好多文件。」與大多數強調更有序和結構化程度更高的技術一樣,對於 Struts 和 Tiles,在一開始需要在管理文件上花些工夫。對於只有少許頁面的小項目,這一額外開銷可能微不足道。然而,隨著項目變大,Struts 和 Tiles 方法逐漸會顯示其優越性。讓我們一點點地體會吧!這裡我不想討論 EX2_INSTALL/src/WEB-INF/web.xml;儘管這個文件實質上與其示例 1 中相對應的文件不同,而且大多數行都是樣板,但理解這些設置對於著手開發並不太重要。

在 EX2_INSTALL/src/WEB-INF/struts-config.xml 中,自先前有關 Struts 的文章以來重要的更改有在 <form-beans/> 節中 DynaActionForm 的使用及在 <action-mappings/> 節中 tile 作為目標的使用。在 Struts 的以前版本中,您必須為每個所使用的表單 bean 定義一個 Java 類。僅當不同的 HTML 表單共享域時,才可以在這些表單之間共享表單 bean。總之,每個表單 bean 需要有一個 Java 類是一個非常麻煩的要求。現在,您可以在 struts-config.xml 文件中指定表單 bean 的特性,而且是迅速地!不必有保存 Java 類的單獨文件,就能自動創建這種 bean。像處理 Hashtable 對像一樣,用值的強類型對像來處理動態表單 bean。至於操作映射,一旦確定將 Tiles 庫合併到 Struts 分發版之後,那麼指定一個 tile 作為目標,就完全是增加一項邏輯而已。您會在概要信息表單的操作映射中看到 tile 目標(tile.profileInput 和 tile.profileOutput)。在 input 屬性和 path 屬性中指定 tile。註:可以指定 tile 目標彌補了我在分析以頁面為中心的模型中提到的更改文件名和位置中的缺陷:tile 目標是虛擬名稱或邏輯名稱,而不是物理名稱。

現在,進入激動人心的部分。讓我們看一下 EX2_INSTALL/src/WEB-INF/tiles-defs.xml。

在 <definition/> 標記中指定 tile。您可以將定義命名為任何希望的名稱,而且 name 屬性不必是與 path 屬性匹配的子字符串。我為第一個定義選擇了名稱 rootLayout,以表明它是應用程序中的頁面要遵循的基本佈局。註:路徑是 /tiles-layout/rootLayout.jsp。如果查看 EX2_INSTALL/src/web 下的 /tiles-layout/rootLayout.jsp,您會看到這種佈局是多麼的簡單整齊。用戶界面的設計人員會「愛上它」。還請注意:它不包含任何代碼,所以用戶界面設計人員在進行更改時不必擔心破壞什麼。

rootLayout.jsp 中的 <tiles:insert/> 標記對應於 tiles-defs.xml 中 rootLayout 定義內的 <put/> 標記。註:每個 <tiles:insert attribute="x"/> 標記都有一個表示邏輯名稱的屬性。每個邏輯名稱映射至通過在 tiles-defs.xml 內的 <definition/> 中使用 <put name="x" value="y"/> 標記指定的名稱和值。通過在 rootLayout.jsp 頁面中使用邏輯名稱,而非物理名稱,並通過在 tiles-defs.xml 中統一物理名稱,我們就可以更改文件名,並使項目文件系統的組織易於管理。

真正節省時間和適應性方面最顯著的增強方面體現在佈局的繼承,這是 Struts 的另一個特性。在 tiles-defs.xml 中,「Page definitions」欄下面的節有兩個頁面:tile.profileInput 和 tile.profileOutput。這些名稱是任意的,如果您不喜歡 tile. 前綴,可以不使用它(但是您使用的名稱必須與 struts-config.xml 文件中指定的目標相匹配)。這些名稱應該與 struts-config.xml 中 <forward name="x" path="y"/> 標記中的 path 屬性匹配。這些名稱還應該與 struts-config.xml 中 <action ... input="" .../> 標記中的 input 屬性匹配。在開發用戶界面時,<definition name="x" extends="y"/> 標記中的 extends 屬性是體現開發靈活性的地方。通過指定主佈局並擴展它,您不僅能靈活更改象 topBanner、topMenu、panel1、panel2 這樣的公共元素及其它組件, 還能隨意地將不同元素放在頁面上及更改它們的位置。例如,您可以添加 panel4(一個 tile)以在頁面左側的 panel2 下顯示本地天氣。只要天氣代碼不需要用戶的任何輸入或與頁面上的其它組件交互,您就可以添加 panel4 而不必對應用程序業務邏輯做任何更改,甚至不必更改除 rootLayout.jsp 以外的 JSP 頁面。

讓我們嘗試將帶有天氣信息的 panel4 添加至應用程序中來看看這樣做是多麼容易。為了節省時間,我已在 EX2_INSTALL/src/web/tiles-components 中名為 panel4.jsp 的文件中創建了天氣組件的 JSP 文件,其中有內容和 HTML 代碼。您需要進行兩個更改:

在 EX2_INSTALL/src/WEB-INF/tiles-defs.xml 中,找到清單 1 中顯示的代碼,然後編輯它以添加用於 panel4 的 <put/> 標記,如清單 2 所示: 

清單 1. 原始 tiles-defs.xml 代碼
<definition name="rootLayout" path="/tiles-layouts/rootLayout.jsp">
<put name="titleString" value="CHANGE-ME"/>
<put name="topBanner" value="/tiles-components/topBanner.jsp"/>
<put name="topMenu" value="/tiles-components/topMenu.jsp"/>
<put name="panel1" value="/tiles-components/panel1.jsp"/>
<put name="panel2" value="/tiles-components/panel2.jsp"/>
<put name="panel3" value="CHANGE-ME"/>
<put name="footer" value="/tiles-components/footer.jsp"/>
<put name="footerDebug" value="/tiles-components/footerDebug.jsp"/>
</definition>




清單 2. 新的 tiles-defs.xml 代碼
<definition name="rootLayout" path="/tiles-layouts/rootLayout.jsp">
<put name="titleString" value="CHANGE-ME"/>
<put name="topBanner" value="/tiles-components/topBanner.jsp"/>
<put name="topMenu" value="/tiles-components/topMenu.jsp"/>
<put name="panel1" value="/tiles-components/panel1.jsp"/>
<put name="panel2" value="/tiles-components/panel2.jsp"/>
<put name="panel4" value="/tiles-components/panel4.jsp"/>
<put name="panel3" value="CHANGE-ME"/>
<put name="footer" value="/tiles-components/footer.jsp"/>
<put name="footerDebug" value="/tiles-components/footerDebug.jsp"/>
</definition>





在 EX2_INSTALL/src/web/tiles-layouts/rootLayout.jsp 中,找到清單 3 中顯示的代碼,然後編輯它以添加 <br> 標記和代碼來插入 panel4,如清單 4 所示: 

清單 3. 原始 rootLayout.jsp 代碼
<td width="35%">
<!-- ============================================================ -->
<!-- Begin panel1 -->
<tiles:insert attribute="panel1"/>
<!-- End panel1 -->
<!-- ============================================================ -->
<br>
<!-- ============================================================ -->
<!-- Begin panel2 -->
<tiles:insert attribute="panel2"/>
<!-- End panel2 -->
<!-- ============================================================ -->
</td>




清單 4. 新的 rootLayout.jsp 代碼
<td width="35%">
<!-- ============================================================ -->
<!-- Begin panel1 -->
<tiles:insert attribute="panel1"/>
<!-- End panel1 -->
<!-- ============================================================ -->
<br>
<!-- ============================================================ -->
<!-- Begin panel2 -->
<tiles:insert attribute="panel2"/>
<!-- End panel2 -->
<!-- ============================================================ -->
<br>
<!-- ============================================================ -->
<!-- Begin panel4 -->
<tiles:insert attribute="panel4"/>
<!-- End panel4 -->
<!-- ============================================================ -->
</td>





註:EX3_INSTALL 中的示例 3 應用程序只是示例 2 加上前面所做的更改;如果有問題,可以使用該代碼。

現在,需要執行一些步驟使 Tomcat 識別新文件:

轉至 TOMCAT_HOME/bin 目錄。


通過輸入 ./shutdown.sh(如果在運行 Unix)或 ./shutdown.bat(如果在運行 Windows)來關閉 Tomcat 服務器。


轉至 EX2_INSTALL 目錄。


輸入 ant undeploy,以從 Tomcat webapp 目錄中除去 ex2.war 文件和解壓的 ex2 目錄。


輸入 ant deploy。


轉至 TOMCAT_HOME/bin 目錄。


通過輸入 ./startup.sh(如果在運行 Unix)或 ./startup.bat(如果在運行 Windows)來啟動 Tomcat 服務器。


將 Web 瀏覽器指向 http://localhost:8080/ex2。重新將頁面裝入瀏覽器,以確保您看到的不是示例 2 Web 應用程序的高速緩存副本。您應該會看到新的帶有天氣組件的「Hello, World」頁面。 
示例 2 應用程序說明了下表 2 中所總結的基於 MVC 的 Struts 和 Tiles Web 應用程序模型的優缺點。

表 2. Struts 和 Tiles 方法的概述 

缺點 說明 
陡峭的學習曲線,要處理較多的移動部件操作。 Struts 和 Tiles 的入門要比普通 JSP 頁面花費的時間長,部分是因為要處理更多的文件和需要進行額外配置。 
優點 說明 
維護更容易,模塊化程度更高。 Tiles 框架使得添加和除去視圖組件及重新安排事物非常容易。Struts 執行類似的行為和業務邏輯功能。 
為公共的輸入和輸出任務預先構建的解決方案。 利用 Struts,您可以自動接受表單並處理錯誤,並以結構化的方法進行。Tiles 框架讓您方便地將不同的輸出窗格組裝成一個集成的整體。 
易於並行地進行業務邏輯和 UI 開發。 因為業務邏輯與顯示相分離,所以在 Java 開發人員開發業務邏輯的 Java 代碼同時,圖形設計人員可以開發用戶界面的 HTML。 
操作、表單和屏幕的集中映射。 由 struts-config.xml 文件和 tiles-defs.xml 文件提供了操作、表單和屏幕的集中映射,這更易於理解整個應用程序,特別是在應用程序很大的情況下。 

Struts 和 Tiles 更複雜的使用
篇幅所限,不允許我再深入討論 Struts 和 Tiles 包其它一些實用的方面,但我真的想簡要地談一下,這樣您可以對 Struts 和 Tiles 可以做些什麼有所瞭解。如果有足夠的需求,可能這些內容會是將來文章的主題。

您會在本文的兩個示例中注意到,我編碼了名、姓、喜歡的顏色和出生日期等基本驗證。我所採用的這類簡單驗證實際上可由 Struts 通過使用它的格式驗證來執行,這樣節省了花在編碼 Java 語句的時間。例如,檢查是否是空字符串、檢查字符串是否與日期相匹配或檢查是否與其它某些正則表達式匹配等,這都是可行的。您會發現將格式驗證用作第一級檢查會是十分方便的,在檢查是否符合更複雜的業務邏輯規則之前,程序可用第一級檢查來消除一些明顯錯誤。Struts 提供了一個驗證器包,可以通過 WEB-INF 目錄中的 validator.xml 描述符來配置該包。在這兩個示例中我沒有包含該驗證器包;如果您想試一下,它包含在 Struts 1.1-b1 包中。

Struts 和 Tiles 包的另一個有用特性是與容器管理的安全性相集成。很多人都在使用諸如 IBM WebSphere 或 JBoss 之類的應用程序服務器。這些服務器通過處理安全性中所涉及的許多日常任務使認證和授權更便捷,讓您擺脫必須對它們進行的編碼。Struts 允許您根據用戶角色有條件地向不同用戶顯示 bean 數據的不同位,這可以通過自動查詢容器來決定。同樣地,Tiles 框架允許您根據用戶角色有條件地向不同用戶顯示不同的視圖組件,這也是通過自動查詢容器來決定的。我在自己的應用程序中使用這些特性向管理員、常規用戶或 guest 用戶顯示不同的菜單。

最後要說明,我在示例中沒有談到國際化,但對於那些構建將來最終要以多種語言發佈的大型應用程序的人來說,這實際是一個重要方面。Struts 讓您創建消息資源特性文件,這些文件指定標籤、標題和其它輸出的文本。如果您用幾種不同語言的輸出填入消息資源特性文件的話,只要簡單更改語言設置就能將所有窗口構件和硬編碼的文本更改成適當語言,甚至在應用程序運行中也可以更改。

未來的方向
Struts 和 Tiles 將走向何方呢?剛出現的兩個更改必定會使 Struts 和 Tiles 更加有用。第一個更改是工作流管理系統。您很可能處理過許多多步驟的業務過程;目前,在 Web 應用程序中對它們進行編碼可以是一個主要的麻煩,因為您必須協調不同的步驟,而每一步驟都是 Java 類中的一個單獨方法或是一個單獨的 servlet 或 JSP 頁面。商業市場中的工具通過使開發人員能對多步驟的業務過程進行建模,然後自動生成 Java 代碼作為進一步開發的基礎,來幫助管理這些過程。Struts 工作流管理系統將提供類似的功能,使開發人員能夠編寫業務過程的腳本,這些過程在 Web 應用程序中跨多個頁面,並指定這些頁面如何通過核心的基於規則的系統進行交互。

另一個同樣有望即將出現的更改是將 Struts 標記合併到 JSP 標準標記庫(JSP Standard Tag Library)中,這個庫是 Jakarta 項目,它試圖產生一個有用的定制標記集合,從而簡化並加快用 JSP 頁面編寫 Web 應用程序的開發。其中的意義在於:Web 應用程序的開發將比過去任何時候都更容易,因為您可以通過使用定制標記的標準機制得到一個在此基礎上做進一步開發的預先編寫好的代碼庫。而且,JSP STL 標準中這個項目的合併甚至確保了 Struts 和 Tiles 功能更為廣泛的分發和可用,這意味具有這種技能的開發人員在眾多項目中大有作為,而且公司更加容易獲得開發 Web 應用程序的熟練人才。

您能從本文中獲得什麼?
在閱讀了本文後,您應該記住以下要點:

MVC 是開發健壯的 Web 軟件的優秀體系結構。面向頁面的體系結構是簡單的,但隨著應用程序在規模和使用範圍方面的增長會逐漸失去作用。MVC 是一種經證實適合於較大型應用程序的模型。


Struts 和 Tiles 為複雜應用程序提供一個堅實的基礎。Struts 和 Tiles 符合 MVC 範例,並允許開發人員創建隨業務需要在管理狀態下增長的應用程序。


Struts 和 Tiles 受到強大的業界支持,並在開發人員中有逐漸流行和具有推動力。這確保了其被廣泛採用,並保護了開發人員和公司投入的時間和金錢。 
有了 Struts 和 Tiles,您會發現現在創立您自己的 Web 應用程序更加容易了。

參考資料 

請通過單擊文章頂部或底部的討論,參與關於本文的論壇。 


下載以 zip 文件或 tgz 文件形式提供給大家的本文中的示例代碼。


在 Jakarta Struts 主頁上查找更多有關 Struts 的信息。


研究 Tiles 並查找文檔。


如有疑問,可以通過這些郵件列表 struts-user、tomcat-user、commons-dev 和 taglibs-user 尋求幫助,這些郵件列表都位於 Jakarta 站點。


獲得 Tomcat JSP/servlet。


要瞭解有關實用開放源碼庫 taglibs 的更多信息,請訪問 Jakarta taglibs 站點。


有關 Struts 的入門級簡介,請參閱 Malcolm Davis 所寫的「Struts, an open-source MVC implementation」(developerWorks,2001 年 2 月)。


在 IBM VisualAge 開發者園地中還有一篇非常好的關於帶有 IBM 工具的 Struts 的參考文章,它是由 Kyle Brown 所寫的「Apache Struts 與 VisualAge for Java,第一部分:使用 Apache Struts 構建基於 Web 的應用程序」(2001 年 5 月)。


如果您希望瞭解有關「模型-視圖-控制器」框架的更多背景知識,請查看 Wayne Beaton 的「Migrating to IBM WebSphere Application Server, Part 1: Designing software for change」(WebSphere Developer Technical Journal,2001 年 7 月)。


IBM WebSphere 是一個功能齊全的出色的應用程序服務器;一旦您的應用程序開發比本文中的簡單示例更複雜,就會需要這樣一個服務器。


JBoss 是一個也能滿足應用程序開發需要的開放源碼的應用程序。


下載 J2SE 1.4 SDK。


從 Jakarta 站點上 Ant 1.4 構建工具的主頁上獲取該工具。


在 developerWorks Java 技術專區可以找到其它 Java 技術參考資料。

webasp.net