Struts1 v.s Struts2
作為最受歡迎的Web framework,Struts擁有眾多的優點,如實踐MVC2 model、功能齊全的Tag Library及Open Source等。但隨著Web AP的發展及應用越來越多元,Struts1也有不少的缺點讓使用者詬病,如Unit test困難及容易造成class過多等問題,進而衍生出了Struts2。
做為Struts1缺點的解決方案,Struts2與Struts1主要區別如下:
一、Action Class
Action是整個Struts1 framework的核心內容, Struts2也不例外。不過兩者的Action model有著很大的區別。其中的關鍵在於Struts2是一個pull-MVC架構。這代表了需要顯示給使用者的資料可以直接從Action中取得,而不用和Struts1一般,需把相對應的Bean物件存到Page、Request或者Session等Scope中才能獲取。
進一步說明,在Struts1中,Action必須繼承org.apache.struts.action.Action或其子類別,並將Form表單參數封裝在FormBean中。然而在Struts2中,Action無須繼承任何class或實現任何interface,Form表單參數可直接包含在Action中,透過get和set的方法取得。
(可參考下面的Struts2Action.java sample)
ps:雖然,在理論上Struts2的Action無須實現任何接口或者是繼承任何的類,不過在實際coding的過程中,為了更加方便的實現Action,大多數情況下還是會繼承com.opensymphony.xwork2.ActionSupport類,並且覆寫(Override)此類裡的String execute()方法。
Struts2Action.java
package com.demo.action;
import com.opensymphony.xwork2.ActionSupport;
public class Struts2Action extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String execute() throws Exception {
System.out.println(message);
return SUCCESS;
}
}
從Struts
另外,按照慣例,在Struts1中只有「execute」方法能呼叫Action, 但在Struts2中並非必要,任何聲明為public String methodName() 方法,都能通過配置struts.xml來呼叫Action。
最後,和Struts1最大革命性的不同是,Struts2處理Action過程中呼叫的方法execute()是不帶參數的,而是利用IoC(反轉控制)的方式獲取所需參數。
二、反轉控制 IoC(Inversion of Control)
亦稱為依賴注入(Dependency Injection)模式,Spring framework使得這個模式流行起來,然而Struts2的前身WebWork也同時應用上了這個模式。
想更瞭解IoC相關資訊的請參考這篇Martin Fowler的文章
Inversion of Control Containers and the Dependency Injection pattern
三、攔截器(Interceptor)
攔截是AOP(Aspect-Oriented Programming)的一種實現策略。而攔截器是動態攔截Action呼叫的對象。它提供了一種機制可以使開發者定義在一個action執行的前後執行的程式碼,也可以在一個action執行前阻止其執行。同時也提供了一種可以提取action中可重用的部分的方式。
Struts1的標準框架中不提供任何形式的攔截器,雖有一個名為SAIF的plug in實現了類似的功能,但它適用的範圍還很有限。
攔截器是Struts2的一個強有力的工具,有許多功能都是基建於它之上,如國際化、轉換器,驗證等。Struts 2已經提供各式功能齊全的攔截器實現。可到struts-default.xml查看關於默認的攔截器配置。
Struts2不僅在Action方面做出改變,還加強了對AOP與IoC的支持,而這些特性在Struts1中是很難想像的。至此不難瞭解, Struts2是WebWork的升級,而不是Struts1的升級。雖然Struts 2提供了與Struts1的兼容,但已經不是Struts1的升級。
結論
因此對於已有Struts1開發經驗的開發者而言,Struts1的開發經驗對於Struts2並沒有太大的幫助;相反,對於已經有WebWork開發經驗的開發者而言,WebWork的開發經驗對Struts2的開發將是一個很好的借鏡。
Struts1與Struts2整體比較整理如下表
特性 | Struts1 | Struts2 |
Action類 Action classes | 要求Action類要繼承一個抽象類別(abstract)。Struts1.x的問題在於使用一個abstract類別取代使用interfaces。 | Action可以實作一個Action interface,也可實現其他自定義的interfaces提供服務。Struts2提供一個基本的ActionSupport class去實現常用的interfaces。然而Action interface並不是必要的,任何有execute方法的POJO class都可以作為Struts2的Action。 |
線程模型 Threading Model | Struts1 Action是單例模式並且必須是線程安全的,因為僅有Action的一個實例來處理所有的請求。單例策略限制了Struts1 Action能作的事,並且要在開發時特別小心。Action資源必須是線程安全的或同步的。 | Struts2 Action對象為每一個請求產生一個實例,因此沒有線程安全問題。(實際上,servlet容器給每個請求產生許多可丟棄的對象,並且不會導致性能和垃圾回收問題) |
Servlet 依賴 Servlet Dependency | Struts1 Action 依賴於Servlet API ,因為當一個Action被調用時HttpServletRequest 和 HttpServletResponse 被傳遞給execute方法。 | Struts |
易測性 Testability | 測試Struts | Struts |
截取輸入 Harvesting Input | Struts1 使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個基類。因為其他JavaBean不能用作ActionForm,開發者經 常創建多餘的類捕獲輸入。動態Bean(DynaBeans)可以作為創建傳統ActionForm的選擇,但是,開發者可能是在重新描述(創建)已經存在的JavaBean,仍然會導致有冗餘的JavaBean。 | Struts 2直接使用Action屬性作為輸入屬性,消除了對第二個輸入對象的需求。輸入屬性可能是有自己(子)屬性的rich對象類型。Action屬性能夠通過web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包括業務對象,能夠用作輸入/輸出對象。這種ModelDriven 特性簡化了taglib對POJO輸入對象的引用。 |
表達式語言 Expression Language | Struts1 整合了JSTL,因此使用JSTL EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。 | Struts2可以使用JSTL,但是也支持一個更強大和靈活的表達式語言--"Object Graph Notation Language" (OGNL). |
將值綁定到頁面 Binding values into views | Struts 1使用標準JSP機制把對象綁定到頁面中來訪問。 | Struts 2 使用「ValueStack」技術,使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來。ValueStack策略允許通過一系列名稱相同但類型不同的屬性重用頁面(view)。 |
類型轉換 Type Conversion | Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進行類型轉換。每個類一個轉換器,對每一個實例來說是不可配置的。 | Struts2 使用OGNL進行類型轉換。提供基本和常用對象的轉換器。 |
驗證 Validation | Struts 1支持在ActionForm的validate方法中手動校驗,或者通過Commons Validator的擴展來校驗。同一個類可以有不同的校驗內容,但不能校驗子對象。 | Struts2支持通過validate方法和XWork校驗框架來進行校驗。XWork校驗框架使用為屬性類類型定義的校驗和內容校驗,來支持chain校驗子屬性 |
Action執行控制 Control Of Action Execution | Struts1支持每一個模塊有單獨的Request Processors(生命週期),但是模塊中的所有Action必須共享相同的生命週期。 | Struts2支持通過Interceptor Stacks為每一個Action創建不同的生命週期。Stacks能夠根據需要和不同的Action一起使用。 |
Comparing the Struts 1 and Struts 2 Web Application Frameworks
Labels: Struts2 系列 •
0 comments :
Post a Comment