Struts 1.x 與 Struts2 的區別

Struts1和Struts2的區別和對比  
Struts1和Struts2的區別和對比 
• Struts1要求Action類繼承一個抽象基類。Struts1的一個普遍問題是使用抽象類編程而不是接口。  
• Struts 2 Action類可以實現一個Action接口,也可實現其他接口,使可選和定製的服務成爲可能。Struts2提供一個ActionSupport基類去 實現 常用的接口。Action接口不是必須的,任何有execute標識的POJO對象都可以用作Struts2的Action對象。  
線程模式:  
• Struts1 Action是單例模式並且必須是線程安全的,因爲僅有Action的一個實例來處理所有的請求。單例策略限制了Struts1 Action能作的事,並且要在開發時特別小心。Action資源必須是線程安全的或同步的。  
• Struts2 Action對象爲每一個請求產生一個實例,因此沒有線程安全問題。(實際上,servlet容器給每個請求產生許多可丟棄的對象,並且不會導致性能和垃圾回收問題)  

Servlet 依賴:  
• Struts1 Action 依賴於Servlet API ,因爲當一個Action被調用時HttpServletRequest 和 HttpServletResponse 被傳遞給execute方法。  
• Struts 2 Action不依賴於容器,允許Action脫離容器單獨被測試。如果需要,Struts2 Action仍然可以訪問初始的request和response。但是,其他的元素減少或者消除了直接訪問HttpServetRequest 和 HttpServletResponse的必要性。  

可測性:  
• 測試Struts1 Action的一個主要問題是execute方法暴露了servlet API(這使得測試要依賴於容器)。一個第三方擴展--Struts TestCase--提供了一套Struts1的模擬對象(來進行測試)。  
• Struts 2 Action可以通過初始化、設置屬性、調用方法來測試,“依賴注入”支持也使測試更容易。  

捕獲輸入:  
• Struts1 使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個基類。因爲其他JavaBean不能用作ActionForm,開發者經 常創建多餘的類捕獲輸入。動態Bean(DynaBeans)可以作爲創建傳統ActionForm的選擇,但是,開發者可能是在重新描述(創建)已經存 在的JavaBean(仍然會導致有冗餘的javabean)。  
• Struts 2直接使用Action屬性作爲輸入屬性,消除了對第二個輸入對象的需求。輸入屬性可能是有自己(子)屬性的rich對象類型。Action屬性能夠通過 web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包括業務對象,能夠用作輸入/輸出對象。這種 ModelDriven 特性簡化了taglib對POJO輸入對象的引用。  

表達式語言:  
• Struts1 整合了JSTL,因此使用JSTL EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。  
• Struts2可以使用JSTL,但是也支持一個更強大和靈活的表達式語言--"Object Graph Notation Language" (OGNL).  

綁定值到頁面(view):  
• Struts 1使用標準JSP機制把對象綁定到頁面中來訪問。  
• Struts 2 使用 "ValueStack"技術,使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來。ValueStack策略允許通過一系列名稱相同但類型不同的屬性重用頁面(view)。  
   
類型轉換:  
• Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進行類型轉換。每個類一個轉換器,對每一個實例來說是不可配置的。  
• Struts2 使用OGNL進行類型轉換。提供基本和常用對象的轉換器。  

校驗:  
• Struts 1支持在ActionForm的validate方法中手動校驗,或者通過Commons Validator的擴展來校驗。同一個類可以有不同的校驗內容,但不能校驗子對象。  
• Struts2支持通過validate方法和XWork校驗框架來進行校驗。XWork校驗框架使用爲屬性類類型定義的校驗和內容校驗,來支持chain校驗子屬性  

Action執行的控制:  
• Struts1支持每一個模塊有單獨的Request Processors(生命週期),但是模塊中的所有Action必須共享相同的生命週期。  
• Struts2支持通過攔截器堆棧(Interceptor Stacks)爲每一個Action創建不同的生命週期。堆棧能夠根據需要和不同的Action一起使用。 

Struts作爲MVC 2的Web框架,自推出以來不斷受到開發者的追捧,得到廣泛的應用。作爲最成功的Web框架,Struts自然擁有衆多的優點:MVC 2模型的使用、功能齊全的標誌庫(Tag Library)、開放源代碼。

但是,正所謂“沒有最好,只有更好”,Struts1.x自身也有不少的缺點:需要編寫的代碼過多,容易引起“類爆炸”、單元測試困難。這些缺點隨着Web的發展越來越明顯。這就促生了Struts 2,它的誕生能很好的解決上述問題。

在本文中,筆者將對Struts2和Struts1.x這兩種框架進行詳細的比較。比較將涉及到這兩種框架的Action、驗證、類型轉換及如何開發等方面的內容。希望通過這樣的比較,讓讀者瞭解這兩種框架各自的特點,以便於在自己的項目中,根據實際情況,儘快的過渡到Struts2的時代。本文的內容基於Struts2.0.6。

 

一、       引言

 

Struts的第一個版本是在2001年5月份發佈的。它的最初設想是通過結合JSP和Servlet,使Web應用的視圖和業務/應用邏輯得以清晰地分離開來。在Struts之前,最常見的做法是在JSP中加入業務和應用邏輯,或者在Servlet中通過println()來生成視圖。

自從第一版發佈以來,Struts實際上已成爲業界公認的Web應用標準。它的炙手可熱也爲自己帶來了改進和變更,所以不但要跟上對Web應用框架不斷變化的需求,而且要與日漸增多競爭激烈的衆多框架的特性相融合。

到最後,產生了幾個下一代Struts的解決方案。其中兩個最受矚目的方案是Shale和Struts Ti。Shale是一個基於構件的框架,並在最近成爲Apache的頂級項目。而Struts Ti則是在Struts的成功經驗基礎上繼續堅持對前端控制器(Front Controller)和MVC(model-view-controller)模式進行改進。

WebWork項目是在2002年3月發佈的,它對Struts式框架進行了革命性改進,引進了不少新的思想、概念和功能,但和原Struts代碼並不兼容。WebWork是一個成熟的框架,經過了好幾次重大的改進與發佈。

在2005年12月,WebWork與Struts Ti宣佈合併。與此同時,Struts Ti改名爲Struts Action Framework 2.0,成爲Struts真正的繼承者。

最後要注意的是,並不是說Struts或WebWork項目已經停止開發了。由於人們對這兩個項目的興趣仍然很高,而且也有很多開發者仍然願意使用它們,因此這兩個項目還在繼續開發中,繼續修復Bug,改進功能和繼續添加新功能。

 

二、       Action的區別

 

對於有着豐富的Struts1.x開發經驗的朋友來說,都十分的清楚Action是整個Struts框架的核心內容,當然Struts2也不例外。不過,Struts1.x與Struts2的Action模型很大的區別。

Struts2和Struts1.x的差別,最明顯的就是Struts2是一個pull-MVC架構。這是什麼意思呢?從開發者角度看,就是說需要顯示給用戶的數據可以直接從Action中獲取,而不像Struts1.x那樣,必須把相應的Bean存到Page、Request或者Session中才能獲取。Struts1.x 必須繼承org.apache.struts.action.Action或者其子類,表單數據封裝在FormBean中。Struts 2無須繼承任何類型或實現任何接口,表單數據包含在Action中,通過Getter和Setter獲取(如下面的ActionForStruts2的代碼示例)。

雖然,在理論上Struts2的Action無須實現任何接口或者是繼承任何的類,但是,在實際編程過程中,爲了更加方便的實現Action,大多數情況下都會繼承com.opensymphony.xwork2.ActionSupport類,並且重載(Override)此類裏的String execute()方法。如下所示:

package ActionDiffer;

 import java.text.DateFormat;

 import java.util.Date;

 

 import com.opensymphony.xwork2.ActionSupport;

 

 public class ActionForStruts2 extends ActionSupport {

     private String message;

   

     public String getMessage() {

         return message;

    }

   

    @Override

     public String execute() {

        message = " This is hello from strtuts2. Now is: " + DateFormat.getInstance().format( new Date());

         return SUCCESS;

    }

}

首先,從ActionForStruts2可以看出,返回的對象不是ActionForward,而是String。如果你不喜歡以字符串的形式出現在你的代碼中,有個Helper接口Action可以以常量方式提供常見結果,如“success”、“none”、“error”、“input”和“login”。

另外, 按照慣例,在Struts1.x中只有“execute”方法能調用Action, 但在Struts2中並非必要,任何聲明爲public String methodName() 方法,都能通過配置來調用Action。

最後,和Struts1.x最大的革命性的不同是,Struts2處理Action過程中調用的方法(“execute”方法)是不帶參數的。那如何獲取所需要的對象呢?答案是使用IoC(反轉控制,Inversion of Control),也叫“依賴注入(Dependency Injection)”的模式(想更多地瞭解這方面信息請看Martin Fowler的文章http://www.martinfowler.com/articles/injection.html)。Spring框架使得這個模式流行起來,然而Struts2的前身(WebWork)也同時應用上了這個模式。

 

三、       IoC

IoC(Inversion of Control,以下譯爲控制反轉),隨着Java社區中輕量級容器(Lightweight Contianer)的推廣而越來越爲大家耳熟能詳。在此,無需再多費脣舌來解釋“什麼是控制反轉”和“爲什麼需要控制反轉”。因爲互聯網上已經有非常多的文章對諸如此類的問題作了精彩而準確的回答。讀者可以去讀一下Rod Johnson和Juergen Hoeller合著的《Expert one-on-one J2EE Development without EJB》或Martin Fowler所寫的《Inversion of Control Containers and the Dependency Injection pattern》。

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