程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Jakarta Struts應用的七個經驗

Jakarta Struts應用的七個經驗

編輯:關於JAVA

編者按:本文敘述了作者在運用Struts過程中來之不易的若干經驗和心得。如果你是jsp和servlet開發Web應用的Java程序員,並且也正在考慮采用基於Struts的構建方法的話,那麼你會在這裡發現很多頗有見地同時也很有價值的信息。

1. 只在必要的時候才考慮擴展Struts框架

一個好的framework有很多優點,首先,它必須能夠滿足用戶的可預見的需求。為此 Struts為Web 應用提供了一個通用的架構,這樣開發人員可以把精力集中在如何解決實際業務問題上。其次,一個好的framework還必須能夠在適當的地方提供擴展接口,以便應用程序能擴展該框架來更好的適應使用者的實際需要。

如果Struts framework在任何場合,任何項目中都能很好的滿足需求,那真是太棒了。但是實際上,沒有一個框架聲稱能做到這一點。一定會有一些特定的應用需求是框架的開發者們無法預見到的。因此,最好的辦法就是提供足夠的擴展接口,使得開發工程師能夠調整struts來更好的符合他們的特殊要求。

在Struts framework中有很多地方可供擴展和定制。幾乎所有的配置類都能被替換為某個用戶定制的版本,這只要簡單的修改一下Struts的配置文件就可以做到。

其他組件如ActionServlet和 RequestProcessor 也能用自定義的版本代替. 甚至連Struts 1.1裡才有的新特性也是按照擴展的原則來設計的。例如,在異常處理機制中就允許用戶定制異常處理的句柄,以便更好的對應用系統發生的錯誤做出響應。

作為框架的這種可調整特性在它更適合你的應用的同時也在很大的程度上影響了項目開發的效果。首先,由於您的應用是基於一個現有的成熟的、穩定的framework如Struts,測試過程中發現的錯誤數量將會大大減少,同時也能縮短開發時間和減少資源的投入。因為你不再需要投入開發力量用於編寫基礎框架的代碼了。

然而, 實現更多的功能是要花費更大的代價的。我們必須小心避免不必要的濫用擴展性能, Struts是由核心包加上很多工具包構成的,它們已經提供了很多已經實現的功能。因此不要盲目的擴展Struts框架,要先確定能不能采用其他方法使用現有的功能來實現。 在決定編寫擴展代碼前務必要確認Struts的確沒有實現你要的功能。否則重復的功能會導致混亂將來還得花費額外的精力清除它。

2. 使用異常處理聲明

要定義應用程序的邏輯流程,成熟的經驗是推薦在代碼之外,用配置的方法來實現,而不是寫死在程序代碼中的。在J2EE中,這樣的例子比比皆是。從實現EJB的安全性和事務性行為到描述JMS消息和目的地之間的關系,很多運行時的處理流程都是可以在程序之外定義的。

Struts 創建者從一開始就采用這種方法,通過配置Struts的配置文件來定制應用系統運行時的各個方面。這一點在版本1.1的新特性上得到延續,包括新的異常處理功能。在Struts framework以前的版本中,開發人員不得不自己處理Struts應用中發生的錯誤情況。在最新的版本中,情況大大的改觀了,Struts Framework提供了內置的一個稱為 ExceptionHandler 的類, 用於系統缺省處理action類運行中產生的錯誤。這也是在上一個技巧中我們提到的framework許多可擴展接口之一。

Struts缺省的 ExceptionHandler類會生成一個ActionError對象並保存在適當的范圍(scope)對象中。這樣就允許JSP頁面使用錯誤類來提醒用戶出現什麼問題。如果你認為這不能滿足你的需求,那麼可以很方便的實現你自己的ExcepionHandler類。

具體定制異常處理的方法和機制

要定制自己的異常處理機制,第一步是繼承org.apache.struts.action.ExceptionHandler類。這個類有2個方法可以覆蓋,一個是excute()另外一個是storeException(). 在多數情況下,只需要覆蓋其中的excute()方法。下面是ExceptionHandler類的excute()方法聲明:

正如你看到的,該方法有好幾個參數,其中包括原始的異常。方法返回一個ActionForward對象,用於異常處理結束後將controller類帶到請求必須轉發的地方去。

當然您可以實現任何處理,但一般而言,我們必須檢查拋出的異常,並針對該類型的異常進行特定的處理。缺省的,系統的異常處理功能是創建一個出錯信息,同時把請求轉發到配置文件中指定的地方去。 定制異常處理的一個常見的例子是處理嵌套異常。假設該異常包含有嵌套異常,這些嵌套異常又包含了其他異常,因此我們必須覆蓋原來的execute()方法,對每個異常編寫出錯信息。

一旦你創建了自己的ExceptionHandler 類,就應該在Struts配置文件中的部分聲明這個類,以便讓Struts知道改用你自定義的異常處理取代缺省的異常處理.

可以配置你自己的ExceptionHandler 類是用於Action Mapping特定的部分還是所有的Action對象。如果是用於Action Mapping特定的部分就在元素中配置。如果想讓這個類可用於所有的Action對象,可以在 元素中指定。例如,假設我們創建了異常處理類CustomizedExceptionHandler用於所有的Action類, 元素定義如下所示:

在元素中可以對很多屬性進行設置。在本文中,最重要的屬性莫過於handler屬性, handler屬性的值就是自定義的繼承了ExceptionHandler類的子類的全名。 假如該屬性沒有定義,Struts會采用自己的缺省值。當然,其他的屬性也很重要,但如果想覆蓋缺省的異常處理的話,handler無疑是最重要的屬性。

最後必須指出的一點是,你可以有不同的異常處理類來處理不同的異常。在上面的例子中,CustomizedExceptionHandler用來處理任何java.lang.Exception的子類. 其實,你也可以定義多個異常處理類,每一個專門處理不同的異常樹。下面的XML片斷解釋了如何配置以實現這一點。

在這裡,一旦有異常拋出,struts framework將試圖在配置文件中找到ExceptionHandler,如果沒有找到,那麼struts將沿著該異常的父類鏈一層層往上找直到發現匹配的為止。因此,我們可以定義一個層次型的異常處理關系結構,在配置文件中已經體現了這一點。

3. 使用應用模塊(Application Modules)

Struts 1.1的一個新特性是應用模塊的概念。應用模塊允許將單個Struts應用劃分成幾個模塊,每個模塊有自己的Struts配置文件,JSP頁面,Action等等。這個新特性是為了解決大中型的開發隊伍抱怨最多的一個問題,即為了更好的支持並行開發允許多個配置文件而不是單個配置文件。

注:在早期的beta版本中,該特性被稱為子應用(sub-applications),最近的改名目的是為了更多地反映它們在邏輯上的分工。

顯然,當很多開發人員一起參加一個項目時,單個的Struts配置文件很容易引起資源沖突。應用模塊允許Struts按照功能要求進行劃分,許多情況已經證明這樣更貼近實際。例如,假設我們要開發一個典型的商店應用程序。可以將組成部分劃分成模塊比如catalog(商品目錄), customer(顧客), customer service(顧客服務), order(訂單)等。每個模塊可以分布到不同的目錄下,這樣各部分的資源很容易定位,有助於開發和部署。圖1 顯示了該應用的目錄結構。

圖 1. 一個典型的商店應用程序的目錄結構

注:如果你無需將項目劃分成多個模塊,Struts框架支持一個缺省的應用模塊。這就使得應用程序也可以在1.0版本下創建,具有可移植性,因為應用程序會自動作為缺省的應用模塊。

為了使用多應用模塊功能,必須執行以下幾個准備步驟:

· 為每個應用模塊創建獨立的Struts配置文件。

· 配置Web 部署描述符 Web.xml文件。

· 使用org.apache.struts.actions.SwitchAction 來實現程序在模塊之間的跳轉.

創建獨立的Struts配置文件

每個Struts應用模塊必須擁有自己的配置文件。允許創建自己的獨立於其他模塊的Action,ActionForm,異常處理甚至更多。

繼續以上面的商店應用程序為例,我們可以創建以下的配置文件:一個文件名為struts-config-catalog.xml,包含catalog(商品目錄)、items(商品清單)、和其它與庫存相關的功能的配置信息;另一個文件名為struts- config-order.xml, 包含對order(訂單)和order tracking(訂單跟蹤)的設置。第三個配置文件是struts-config.xml,其中含有屬於缺省的應用模塊中的一般性的功能。

配置Web部署描述符

在Struts的早期版本中,我們在Web.xml中指定Struts配置文件的路徑。好在這點沒變,有助於向後兼容。但對於多個應用模塊,我們需要在Web部署描述符中增加新的配置文件的設定。

對於缺省的應用(包括Struts的早期版本),Struts framework 在Web.xml文件中查找帶有config的元素,用於載入Action mapping 和其它的應用程序設定。作為例子,以下的XML片斷展現一個典型的元素:

注:如果在現有的元素中找不到"config"關鍵字,Struts framework將缺省地使用/WEB/struts-config.xml

為了支持多個應用模塊(Struts 1.1的新特性),必須增加附加的元素。與缺省的元素不同的是,附加的元素與每個應用模塊對應,必須以config/xxx的形式命名,其中字符串xxx代表該模塊唯一的名字。例如,在商店應用程序的例子中,元素可定義如下(注意粗體字部分):

第一個 元素對應缺省的應用模塊。第二和第三個元素分別代表非缺省應用模塊catalog 和 order。

當Struts載入應用程序時,它首先載入缺省應用模塊的配置文件。然後查找帶有字符串config/xxx 形式的附加的初始化參數。對每個附加的配置文件也進行解析並載入內存。這一步完成後,用戶就可以很隨意地用config/後面的字符串也就是名字來調用相應的應用模塊。

多個應用模塊之間調用Action類

在為每個應用模塊創建獨立的配置文件之後,我們就有可能需要調用不同的模塊中Action。為此必須使用Struts框架提供的SwitchAction類。Struts 會自動將應用模塊的名字添加到URL,就如Struts 自動添加應用程序的名字加到URL一樣。應用模塊是對框架的一個新的擴充,有助於進行並行的團隊開發。如果你的團隊很小那就沒必要用到這個特性,不必進行模塊化。當然,就算是只有一個模塊,系統還是一樣的運作。

4. 把JSP放到WEB-INF後以保護JSP源代碼

為了更好地保護你的JSP避免未經授權的訪問和窺視, 一個好辦法是將頁面文件存放在Web應用的WEB-INF目錄下。

通常JSP開發人員會把他們的頁面文件存放在Web應用相應的子目錄下。一個典型的商店應用程序的目錄結構如圖2所示。跟catalog (商品目錄)相關的JSP被保存在catalog子目錄下。跟customer相關的JSP,跟訂單相關的JSP等都按照這種方法存放。

圖 2.基於不同的功能 JSP 被放置在不同的目錄下

這種方法的問題是這些頁面文件容易被偷看到源代碼,或被直接調用。某些場合下這可能不是個大問題,可是在特定情形中卻可能構成安全隱患。用戶可以繞過Struts的controller直接調用JSP同樣也是個問題。

為了減少風險,可以把這些頁面文件移到WEB-INF 目錄下。基於Servlet的聲明,WEB-INF不作為Web應用的公共文檔樹的一部分。因此,WEB-INF 目錄下的資源不是為客戶直接服務的。我們仍然可以使用WEB-INF目錄下的JSP頁面來提供視圖給客戶,客戶卻不能直接請求訪問JSP。

采用前面的例子,圖3顯示將JSP頁面移到WEB-INF 目錄下後的目錄結構

圖 3. JSP存放在 WEB-INF 目錄下更為安全

如果把這些JSP頁面文件移到WEB-INF 目錄下,在調用頁面的時候就必須把"WEB-INF"添加到URL中。例如,在一個Struts配置文件中為一個logoff action寫一個Action mapping。其中JSP的路徑必須以"WEB-INF"開頭。如下所示:請注意粗體部分.

這個方法在任何情況下都不失為Struts實踐中的一個好方法。是唯一要注意的技巧是你必須把JSP和一個Struts action聯系起來。即使該Action只是一個很基本的很簡單JSP,也總是要調用一個Action,再由它調用JSP。

最後要說明的是,並不是所有的容器都能支持這個特性。WebLogic早期的版本不能解釋Servlet聲明,因此無法提供支持,據報道在新版本中已經改進了。總之使用之前先檢查一下你的Servlet容器。

5. 使用 Prebuilt Action類提升開發效率

Struts framework帶有好幾個prebuilt Action類,使用它們可以大大節省開發時間。其中最有用的是org.apache.struts.actions.ForwardAction 和 org.apache.struts.actions.DispatchAction.

使用 ForwardAction

在應用程序中,可能會經常出現只要將Action對象轉發到某個JSP的情況。在上一點中曾提到總是由Action調用JSP是個好習慣。如果我們不必在Action中執行任何業務邏輯,卻又想遵循從Action訪問頁面的話,就可以使用ForwardAction,它可以使你免去創建許多空的Action類。運用ForwardAction的好處是不必創建自己的Action類,你需要做的僅僅是在Struts配置文件中配置一個Action mapping。

舉個例子,假定你有一個JSP文件index.jsp ,而且不能直接調用該頁面,必須讓程序通過一個Action類調用,那麼,你可以建立以下的Action mapping來實現這一點:

正如你看到的,當 /home 被調用時, 就會調用ForwardAction 並把請求轉發到 index.jsp 頁面.

再討論一下不通過一個Action類直接轉發到某個頁面的情況,必須注意我們仍然使用元素中的forward屬性來實現轉發的目標。這時元素定義如下:

以上兩種方法都可以節省你的時間,並有助於減少一個應用所需的文件數。

使用 DispatchAction

DispatchAction是Struts包含的另一個能大量節省開發時間的Action類。與其它Action類僅提供單個execute()方法實現單個業務不同,DispatchAction允許你在單個Action類中編寫多個與業務相關的方法。這樣可以減少Action類的數量,並且把相關的業務方法集合在一起使得維護起來更容易。

要使用DispatchAction的功能,需要自己創建一個類,通過繼承抽象的DispatchAction得到。對每個要提供的業務方法必須有特定的方法signature。例如,我們想要提供一個方法來實現對購物車添加商品清單,創建了一個類ShoppingCartDispatchAction提供以下的方法:

那麼,這個類很可能還需要一個deleteItem()方法從客戶的購物車中刪除商品清單,還有clearCart()方法清除購物車等等。這時我們就可以把這些方法集合在單個Action類,不用為每個方法都提供一個Action類。

在調用ShoppingCartDispatchAction裡的某個方法時,只需在URL中提供方法名作為參數值。就是說,調用addItem()方法的 URL看起來可能類似於:

http://myhost/storefront/action/cart?method=addItem

其中method參數指定ShoppingCartDispatchAction中要調用的方法。參數的名稱可以任意配置,這裡使用的"method"只是一個例子。參數的名稱可以在Struts配置文件中自行設定。

6.使用動態ActionForm

在Struts framework中,ActionForm對象用來包裝HTML表格數據(包括請求),並返回返回動態顯示給用戶的數據。它們必須是完全的JavaBean,並繼承.Struts 裡面的ActionForm類,同時,用戶可以有選擇地覆蓋兩個缺省方法。

該特性能節省很多時間,因為它可以協助進行自動的表現層的驗證。ActionForm的唯一缺點是必須為不同的HTML表格生成多個ActionForm 類以保存數據。例如,如果有一個頁面含有用戶的注冊信息,另一個頁面則含有用戶的介紹人的信息,那麼就需要有兩個不同的ActionForm類。這在大的應用系統中就會導致過多的ActionForm類。Struts 1.1對此做出了很好的改進,引入了動態ActionForm類概念

通過Struts framework中的DynaActionForm類及其子類可以實現動態的ActionForm ,動態的ActionForm允許你通過Struts的配置文件完成ActionForm的全部配置;再也沒有必要在應用程序中創建具體的ActionForm類。具體配置方法是:在Struts的配置文件通過增加一個元素,將type屬性設定成DynaActionForm或它的某個子類的全名。下面的例子創建了一個動態的ActionForm名為logonForm,它包含兩個實例變量:username 和 password.

動態的ActionForm可以用於Action類和JSP,使用方法跟普通的ActionForm相同,只有一個小差別。如果使用普通的ActionForm對象則需要提供get 和 set方法取得和設置數據。以上面的例子而言,我們需要提供getUsername() 和 setUsername()方法取得和設置username變量,同樣地有一對方法用於取得和設置password變量.

這裡我們使用的是DynaActionForm,它將變量保存在一個Map類對象中,所以必須使用DynaActionForm 類中的get(name) 和 set(name)方法,其中參數name是要訪問的實例變量名。例如要訪問DynaActionForm中username的值,可以采用類似的代碼:

String username = (String)form.get("username");

由於值存放在一個Map對象,所以要記得對get()方法返回的Object對象做強制性類型轉換。

DynaActionForm有好幾個很有用的子類。其中最重要的是DynaValidatorForm ,這個動態的ActionForm和Validator 一起利用公共的Validator包來提供自動驗證。這個特性使你得以在程序代碼之外指定驗證規則。將兩個特性結合使用對開發人員來說將非常有吸引力。

7. 使用可視化工具

自從Struts 1.0 分布以來,就出現了不少可視化工具用於協助創建,修改和維護Struts的配置文件。配置文件本身是基於XML格式,在大中型的開發應用中會增大變得很笨拙。為了更方便的管理這些文件,一旦文件大到你無法一目了然的時候,建議試著采用其中的一種GUI 工具協助開發。商業性的和開放源代碼的工具都有不少,表1列出了可用的工具和其相關鏈接,從那裡可以獲取更多信息。

表 1. Struts GUI 工具

應用程序 性質 網址 Adalon 商業軟件 http://www.synthis.com/products/adalon Easy Struts 開放源碼 http://easystruts.sourceforge.net/ Struts Console 免費 http://www.jamesholmes.com/struts/console JForms 商業軟件 http://www.solanasoft.com/ Camino 商業軟件 http://www.scioworks.com/scioworks_camino.html Struts Builder 開放源碼 http://sourceforge.net/projects/rivernorth/ StrutsGUI 免費 http://www.alien-factory.co.uk/struts/struts-index.html
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved