Struts1與Struts2的特點與比較

一.MVC的特點:
— 多個視圖可以對應一個模型。按MVC設計模式,一個模型對應多個視圖,可以減少代碼的複製及代碼的維護量,一旦模型發生改變,也易於維護。
— 模型返回的數據與顯示邏輯分離。模型數據可以應用任何的顯示技術,例如,使用JSP頁面、Velocity模板或者直接產生Excel文檔等。
— 應用被分隔爲三層,降低了各層之間的耦合,提供了應用的可擴展性。
— 控制層的概念也很有效,由於它把不同的模型和不同的視圖組合在一起,完成不同的請求。因此,控制層可以說是包含了用戶請求權限的概念。
—  MVC更符合軟件工程化管理的精神。不同的層各司其職,每一層的組件具有相同的特徵,有利於通過工程化和工具化產生管理程序代碼。

 

二.Struts1的特點
Struts 1以ActionServlet作爲核心控制器,由ActionServlet負責攔截用戶的所有請求。Struts 1框架有3個重要組成部分:Action、ActionForm和ActionForward對象。
ActionForm必須實現ActionForm的基類,設計上並不是真正的POJO
ActionForward就是一個邏輯視圖,通過在配置文件中定義ActionFoward的映射,完成邏輯視圖名和實際視圖資源之間的映射
Struts 1的Action類與Struts 2的Action類有一定的類似性,都通過調用execute方法來處理用戶請求。但最大的區別在於Struts 1 Action的execute方法與Servlet API耦合(ActionServlet繼承自HttpServlet),但Struts 2 Action類的execute方法無需與Servlet API耦合。

struts1的缺陷:
(1).只支持JSP作爲表現層技術,不能與Velocity,FreeMarker等技術整合
(2).與Servlet API嚴重耦合,難於測試
一個exute有四個參數ActionMapping、ActionForm、HttpServletRequest和HttpServletResponse,初始化困難.
(3).侵入式設計,嚴重依賴於Struts1API,如如ActionMapping、ActionForm和ActionForward類.一旦系統需要重構時,這些類完全沒有利用價值,導致較低的代碼複用.

 

三.Struts2的特點
struts2核心控制器:FilterDispatcher
Struts 2用於處理用戶請求的Action實例,並不是用戶實現的業務控制器,而是Action代理——因爲用戶實現的業務控制器並沒有與Servlet API耦合,顯然無法處理用戶請求。而Struts 2框架提供了系列攔截器,該系列攔截器負責將HttpServletRequest請求中的請求參數解析出來,傳入到Action中,並回調Action的execute方法來處理用戶請求。顯然,上面的處理過程是典型的AOP(面向切面編程)處理方式。



 Struts2 Action有以下特點:
—  Action類完全是一個POJO,因此具有很好的代碼複用性。
—  Action類無需與Servlet API耦合,因此進行單元測試非常簡單。
—  Action類的execute方法僅返回一個字符串作爲處理結果,該處理結果可映射到任何的視圖,甚至是另一個Action。

Struts 2的配置文件有兩份:
—配置Action的struts.xml文件。
—配置Struts 2全局屬性的struts.properties文件。

下面是struts.xml配置文件的示例:

Xml代碼
  1. <struts>  
  2.         <!-- Struts 2的Action都必須配置在package裏 -->  
  3.   <package name="default" extends="struts-default">  
  4.          <!-- 定義一個Logon的Action,實現類爲lee.Logon -->  
  5.     <action name="Logon" class="lee.Logon">  
  6.         <!-- 配置Action返回input時轉入/pages/Logon.jsp頁面 -->  
  7.       <result name="input">/pages/Logon.jsp</result>  
  8.         <!-- 配置Action返回cancel時重定向到Welcome的Action-->  
  9.       <result name="cancel" type="redirect-action">Welcome</result>  
  10.         <!-- 配置Action返回success時重定向到MainMenu的Action -->  
  11.       <result type="redirect-action">MainMenu</result>  
  12.         <!-- 配置Action返回expired時進入ChangePassword的Action鏈 -->  
  13.       <result name="expired" type="chain">ChangePassword</result>  
  14.     </action>  
  15.         <!-- 定義Logoff的Action,實現類爲lee.Logoff -->  
  16.     <action name="Logoff" class=" lee.Logoff">  
  17.         <!-- 配置Action返回success時重定向到MainMenu的Action -->  
  18.       <result type="redirect-action">Welcome</result>  
  19.     </action>  
  20.   </package>  
  21. </struts>  
<struts>
        <!-- Struts 2的Action都必須配置在package裏 -->
  <package name="default" extends="struts-default">
         <!-- 定義一個Logon的Action,實現類爲lee.Logon -->
    <action name="Logon" class="lee.Logon">
        <!-- 配置Action返回input時轉入/pages/Logon.jsp頁面 -->
      <result name="input">/pages/Logon.jsp</result>
        <!-- 配置Action返回cancel時重定向到Welcome的Action-->
      <result name="cancel" type="redirect-action">Welcome</result>
        <!-- 配置Action返回success時重定向到MainMenu的Action -->
      <result type="redirect-action">MainMenu</result>
        <!-- 配置Action返回expired時進入ChangePassword的Action鏈 -->
      <result name="expired" type="chain">ChangePassword</result>
    </action>
        <!-- 定義Logoff的Action,實現類爲lee.Logoff -->
    <action name="Logoff" class=" lee.Logoff">
        <!-- 配置Action返回success時重定向到MainMenu的Action -->
      <result type="redirect-action">Welcome</result>
    </action>
  </package>
</struts>

 

四.Struts1與Struts2的比較:
— 在Action實現類方面的對比:Struts 1要求Action類繼承一個抽象基類;Struts 1的一個具體問題是使用抽象類編程而不是接口。Struts 2 Action類可以實現一個Action接口,也可以實現其他接口,使可選和定製的服務成爲可能。Struts 2提供一個ActionSupport基類去實現常用的接口。即使Action接口不是必須實現的,只有一個包含execute方法的POJO類都可以用作Struts 2的Action。

— 線程模式方面的對比:Struts 1 Action是單例模式並且必須是線程安全的,因爲僅有Action的一個實例來處理所有的請求。單例策略限制了Struts 1 Action能做的事,並且要在開發時特別小心。Action資源必須是線程安全的或同步的;Struts 2 Action對象爲每一個請求產生一個實例,因此沒有線程安全問題。

—  Servlet依賴方面的對比:Struts 1 Action依賴於Servlet API,因爲Struts 1 Action的execute方法中有HttpServletRequest和HttpServletResponse方法。Struts 2 Action不再依賴於Servlet API,從而允許Action脫離Web容器運行,從而降低了測試Action的難度。 當然,如果Action需要直接訪問HttpServletRequest和HttpServletResponse參數,Struts 2 Action仍然可以訪問它們。但是,大部分時候,Action都無需直接訪問HttpServetRequest和HttpServletResponse,從而給開發者更多靈活的選擇。

— 可測性方面的對比:測試Struts 1 Action的一個主要問題是execute方法依賴於Servlet API,這使得Action的測試要依賴於Web容器。爲了脫離Web容器測試Struts 1的Action,必須藉助於第三方擴展:Struts TestCase,該擴展下包含了系列的Mock對象(模擬了HttpServetRequest和HttpServletResponse對象),從而可以脫離Web容器測試Struts 1的Action類。Struts 2 Action可以通過初始化、設置屬性、調用方法來測試。

— 封裝請求參數的對比:Struts 1使用ActionForm對象封裝用戶的請求參數,所有的ActionForm必須繼承一個基類:ActionForm。普通的JavaBean不能用作ActionForm,因此,開發者必須創建大量的ActionForm類封裝用戶請求參數。雖然Struts 1提供了動態ActionForm來簡化ActionForm的開發,但依然需要在配置文件中定義ActionForm;Struts 2直接使用Action屬性來封裝用戶請求屬性,避免了開發者需要大量開發ActionForm類的煩瑣,實際上,這些屬性還可以是包含子屬性的Rich對象類型。如果開發者依然懷念Struts 1 ActionForm的模式,Struts 2提供了ModelDriven模式,可以讓開發者使用單獨的Model對象來封裝用戶請求參數,但該Model對象無需繼承任何Struts 2基類,是一個POJO,從而降低了代碼污染。

— 表達式語言方面的對比:Struts 1整合了JSTL,因此可以使用JSTL表達式語言。這種表達式語言有基本對象圖遍歷,但在對集合和索引屬性的支持上則功能不強;Struts 2可以使用JSTL,但它整合了一種更強大和靈活的表達式語言:OGNL(Object Graph Notation Language),因此,Struts 2下的表達式語言功能更加強大。

— 綁定值到視圖的對比:Struts 1使用標準JSP機制把對象綁定到視圖頁面;Struts 2使用“ValueStack”技術,使標籤庫能夠訪問值,而不需要把對象和視圖頁面綁定在一起。

— 類型轉換的對比:Struts 1 ActionForm 屬性通常都是String類型。Struts 1使用Commons-Beanutils進行類型轉換,每個類一個轉換器,轉換器是不可配置的;Struts 2使用OGNL進行類型轉換,支持基本數據類型和常用對象之間的轉換。

— 數據校驗的對比:Struts 1支持在ActionForm重寫validate方法中手動校驗,或者通過整合Commons alidator框架來完成數據校驗。Struts 2支持通過重寫validate方法進行校驗,也支持整合XWork校驗框架進行校驗。

—  Action執行控制的對比:Struts 1支持每一個模塊對應一個請求處理(即生命週期的概念),但是模塊中的所有Action必須共享相同的生命週期。Struts 2支持通過攔截器堆棧(Interceptor Stacks)爲每一個Action創建不同的生命週期。開發者可以根據需要創建相應堆棧,從而和不同的Action一起使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章