摘要:作為一個優秀的MVC框架,Struts得到了廣泛應用。然而,隨著應用領域的擴大,也逐漸暴露出了一些不足。Struts2框架是新推出的一個MVC框架,基于WebWork核心,與Struts相比,具有較大變化。介紹了Struts框架與WebWork框架,詳細分析了Struts2框架的體系結構,通過與Struts框架對比,重點探討了Struts2控制器的實現原理,總結出Struts2的優勢。
關鍵詞:WebWork;Struts1;Struts2;控制器;攔截器;視圖層
中圖分類號:TP311文獻標識碼:A 文章編號:1009-3044(2008)33-1312-02
Research and Analysis of Technology Based on Struts2
GENG Wei, LIU Zhen-hai, SUN Lei
(China University of Mining and Technology, Xuzhou 221008, China)
Abstract: Struts has being applied widely as an excellent framework based on MVC pattern. while the shortage of Struts has being discovered gradually with the expansion of applications. Struts2 is a new MVC framework based on the core of WebWork framework. By contrast with Struts, Struts2 has changed greatly. Describes the WebWork and Struts1 framework, and expatiates the architecture of Struts2. By contrasting Struts2 and Struts, emphatically discusses the principle of the controller, and summarizes the advantage of using Struts2.
Key words: webwork; struts1; struts2; controller; interceptor; viewer
Struts2是APACHE新推出的一個框架,于2007年上半年發布。此前的Struts框架被稱為Struts1。它是世界上發布的第一個MVC框架,得到了廣泛應用,至今已發展成為一個成熟、穩定、性能較高的框架。盡管Struts1框架已經非常地成熟、可靠,但面對大量新興的MVC框架,Struts1逐漸地暴露出了自身的不足,需要不斷地進行更新。因此,Struts2便應運而生了。
相對于Struts1框架而言,Struts2框架是一個全新的框架,盡管兩個框架在名字上相似,但Struts2框架和Struts1框架在體系上的差別非常大。實際上,Struts2并非一個全新的框架,因為Struts2和另外一個MVC框架WebWork非常相似,Struts2是基于WebWork核心的。Struts2更像是一個WebWork的升級版本,從WebWork到Struts2到是一次平滑的過渡。
1 WebWork框架
WebWork框架來自另一個優秀的開源組織opensymphony。WebWork是建立在名叫Xwork的項目基礎之上的。
Xwork簡潔、靈活且功能強大,它是一個標準的Command模式實現,并且完全從web層脫離出來。Xwork提供了很多核心功能:前端攔截器(interceptor),運行時表單屬性驗證,類型轉換,強大的表達式語言(OGNL,the Object Graph Notation Language),IoC(Inversion of Control反轉控制)容器等。
Webwork2建立在Xwork之上,處理HTTP的響應和請求。Webwork2使用ServletDispatcher將HTTP請求變成Action(業務層Action類)、session(會話)及application(應用程序)范圍的映射,request請求參數映射為Webwork2支持的多視圖表示,視圖部分可以使用JSP、Velocity、FreeMarker、JasperRepots、XML等[1]。
2 Struts1框架
Struts1的視圖部分由JSP實現。Struts1提供了豐富的標簽庫,通過這些標簽庫可以減少腳本的使用。Struts1提供了與Ties框架的整合,通過Ties框架提供的模板機制,可以提高網頁的可重用性和可擴展性。但Struts1所支持的表現技術仍非常單一。ActionForm Bean作為數據傳輸對象(DTO),用于在視圖和控制器之間傳遞數據。ActionFormBean通常被劃分到視圖層。
Struts1的控制器由兩部分組成:系統核心控制器和業務邏輯控制器。系統核心控制器為ActionServlet,它繼承HttpServlet類,負責接收所有的HTTP請求,然后根據用戶請求決定是否需要調用業務邏輯控制器。如果需要調用業務邏輯控制器,則將請求轉發給Action處理,否則直接轉向請求的JSP頁面。業務邏輯控制器是用戶自定義的Action類,需要繼承系統的Action類,負責調用模型方法,充當用戶請求和業務邏輯處理之間的適配器[2]。
Struts1的程序運行流程如圖1所示。

圖1 Struts1的程序運行流程
3 Struts2框架
Struts2使用了WebWork設計核心,而不是Struts1設計核心。Struts2框架與WebWork框架相比,在很多方面僅僅是改變了其在WebWork下的名稱。圖2為Struts2體系概圖。
從處理流程上看,Struts2(WebWork)與Struts1類似,它們的核心都由控制器組成。Struts2的控制器也由兩部分組成:核心控制器ServletDispatcher和業務邏輯控制器Action。
Struts2的處理流程如下:
瀏覽器發出請求。
核心控制器FilterDispatccher根據請求決定調用合適的Action。
攔截器鏈自動對請求應用通用功能,如workflow、validation、或文件上傳等功能。
回調Action的execute方法,該方法獲取用戶的請求參數,并調用業務邏輯。
Action的execute方法根據執行結果返回result值,在struts.xml配置文件中,指定result值和視圖資源之間的映射關系。Struts2支持的視圖資源除了JSP以外,還有Velocity、FreeMarker等。
3.1 核心控制器ServletDispatcher
核心控制器是一個Filter,由框架提供。當用戶的請求到達時,它會過濾所有的用戶請求,如果用戶請求以Action結尾,該請求將被轉入Struts2框架處理。Struts2框架根據請求*.action的“*”部分決定調用哪個Action。Action和其實現類之間的對應關系都定義在struts.xml文件中。Struts2框架提供了一系列攔截器,這些攔截器負責將HttpServletRequest請求中的請求參數解析出來,傳入到Action中,并回調Action的execute方法來處理用戶請求。
Interceptor(攔截器)將Action共用的行為獨立出來,在Action執行前后運行。這其實就是AOP(Aspect Oriented Programming,面向方面編程)。Interceptor將很多功能從用戶的Action中獨立出來,減少了Action的大量代碼,獨立出來的行為具有很好的重用性。Struts2的許多功能都是由Interceptor實現,可以在配置文件中組裝Action用到的Interceptor,它會按照指定的順序,在Action執行前后運行。這就將需求功能從不相關類中分離出來;同時,能夠使得很多類共享一個行為,一旦行為發生變化,不必修改很多類,只要修改這個行為就可以。這種處理方式是典型的AOP處理方式。

圖2 Struts2體系概
3.2 業務邏輯控制器Action
業務邏輯控制器Action,由用戶自定義。與Struts1的Action不同,Struts2的Action完全與Servlet API分離,因而該Action更容易測試。Struts2中的Action不再像Struts1中的Action那樣需要繼承Action父類,它可以無需實現任何接口,一個POJO就可以充當Struts2的Action。下面是一個以POJO作為Action的例子:
Public class LoginAction
{ private String username;
private String password;
public String getUsername()
{return username;}
public void setUsername(String username)
{this.username=username;}
public String getPassword();
{return password;}
public void setPassword(String password)
{this.password=password;}
public String execute() throws Exception
{if(getUsername().equals(\"Struts2\")
getPassword().equals(\"123456\")
{return \"success\";}
else
{return \"error\";}
}
}
從以上代碼可以看出,這個Action與POJO的區別就是多了一個無參數的execute方法。在Action的execute方法中,不需要任何參數,這樣設計的一個明顯好處是,不需要把整個Web應用部署到Web容器中,即可對所寫的Action類進行測試,這給開發人員帶來了極大方便。由于它不依賴于servlet請求,更增強了它的可移植、可重用性[2]。
Struts2中Action的屬性可以實現和Struts1中ActionForm的屬性相當的功能,可實現表單數據的封裝,但它們實現的方式是不同的。在Struts2中,是利用框架提供的Interceptor來解析用戶請求,并將請求值賦給Action的對應屬性。
為了讓用戶開發的Action處理類更規范,Struts2提供了一個Action接口,這個接口定義了Struts2的Action處理類應實現的規范。另外,Struts2還提供了Action類的實現類ActionSuport。該類提供了許多默認方法,包括獲取國際化信息的方法、數據校驗的方法、默認的處理用戶請求的方法等,用戶的Action類繼承該類后,將大大簡化Action的開發。
Struts2提供了一個ActionContext類,通過該類可以訪問Servlet API。利用ActionContext來訪問Servlet API,不能直接獲取Servlet API實例,為了在Action中直接訪問Servlet,Struts2還提供了一系列接口:ServletContextAware、ServletRequestAware、ServletResponseAware,Action類實現這些接口,可獲得Servlet API實例。
3.3 Struts2視圖層
Struts2的視圖部分通過大量的標簽提供支持。Struts2標簽庫是Struts2的重要組成部分,Struts2標簽庫提供了非常豐富的功能,這些標簽庫不僅提供了表現層的數據處理,而且提供了流程控制功能、國際化、Ajax支持等功能。
與Struts1標簽相比,Struts2標簽使用OGNL表達式作基礎。因此,對集合、對象的訪問非常便利。Struts2標簽庫將所有標簽都統一到一個標簽庫下,簡化了用戶對標簽庫的使用。
Struts2標簽庫整合了Dojo的支持,因此,可以生成更多頁面表示效果。Struts2提供了許多額外的標簽,包括如日期時間選擇器,樹形結構等。除此之外,借助于底層的DWR支持,Struts2標簽庫提供了Ajax支持,可以通過使用Struts2標簽庫來非常輕松地完成各種Ajax效果。
Struts2提供了主題、模板支持,極大簡化了視圖頁面的編寫,而且它們有很好的可擴展性,如果現有的主題、模板不能滿足項目需求,完全可以開發自定義的主題、模板、可以實現更好的代碼復用;Struts2還允許在頁面中使用自定義組件,這完全能滿足項目中頁面顯示復雜多變的需求[3]。
同WebWork一樣,Struts2對多種表現層技術:JSP、Velocity和FreeMarker等都有很好的支持,從而給開發者更多的選擇,提供了更好的兼容性。
4 結語
Struts2核心控制器使用攔截器機制,具有更高的靈活性和可復用性;Struts2業務邏輯控制器Action可自定義,可不直接與任何的Servlet耦合,增加了代碼的可復用性且更易于測試;Struts2視圖層提供了豐富的標簽庫,而且還支持除JSP以外的其它表現層技術。此外,Struts2還提供了非常靈活的擴展方式:插件。理論上,Struts2可通過插件與任何框架整合,這極大地提高了Struts2的可擴展性。Struts2是一個有前途的框架。
參考文獻:
[1] 唐善成.Webwork原理初探[J].電腦知識與技術,2005(6):83.
[2] 孫衛琴.精通Struts:基于MVC的Java Web設計與開發[M].北京:電子工業出版社,2006:15.
[3] 李剛.Struts2權威指南[M].北京:電子工業版社,2007:309.