Struts是Apache軟件基金會(ASF)贊助的一個(gè)開源項(xiàng)目。它最初是jakarta項(xiàng)目中的一個(gè)子項(xiàng)目,并在2004年3月成為ASF的頂級項(xiàng)目。它通過采用JavaServlet/JSP技術(shù),實(shí)現(xiàn)了基于JavaEEWeb應(yīng)用的MVC設(shè)計(jì)模式的應(yīng)用框架,是MVC經(jīng)典設(shè)計(jì)模式中的一個(gè)經(jīng)典產(chǎn)品。
Struts是作為ApacheJakarta項(xiàng)目的組成部分,項(xiàng)目的創(chuàng)立者希望通過對該項(xiàng)目的研究,改進(jìn)和提高JavaServerPages、servlet、標(biāo)簽庫以及面向?qū)ο蟮募夹g(shù)水準(zhǔn)。
Struts這個(gè)名字的來源于在建筑和舊式飛機(jī)中使用的支持金屬架。之所以這個(gè)框架叫做“struts”,是為了提醒我們記住那些支撐我們房屋,建筑,橋梁,甚至我們踩高蹺的基礎(chǔ)支撐。這也是解釋struts在開發(fā)web應(yīng)用程序中所扮演的角色的精彩描述。
Struts的含義是”支柱,枝干”,它的目的是為了減少程序開發(fā)的時(shí)間,項(xiàng)目的創(chuàng)建者認(rèn)為JSP,servlet的存在雖然可以幫助用戶解決大部分問題,但是由于它們的編碼對項(xiàng)目的開發(fā)帶來了許多的不方便,可重用性也差,所以struts應(yīng)運(yùn)而生,幫助用戶在最短的時(shí)間內(nèi)解決這些問題。Struts框架提供如下服務(wù):
(1)作為控制器的Servlet。
(2)提供大量的標(biāo)簽庫。
(3)提供了用于國際化的框架,利用不同的配置文件,可以幫助用戶選擇合適自己的語言。
(4)提供了JDBC的實(shí)現(xiàn),來定義數(shù)據(jù)源和數(shù)據(jù)庫連接池。
(5)XML語法分析工具。
(6)文件下載機(jī)制。
Struts是對JSPModel2設(shè)計(jì)標(biāo)準(zhǔn)的一種實(shí)現(xiàn),下面分別從模型(Model)、視圖(view)和控制器3個(gè)部分介紹Struts的體系結(jié)構(gòu)和工作原理。調(diào)用流程如下所示(圖1.1)。
圖1.1
(1)視圖(view)
在Struts中,視圖層包含兩個(gè)部分,JSP頁面和ActionForm。
ActionForm封裝了用戶提交的表單信息,其實(shí)ActonForm本質(zhì)上就是JavaBean,這些JavaBean中沒有業(yè)務(wù)邏輯,只提供了所有屬性的getter和setter方法,這些屬性和用戶表單中的輸入項(xiàng)是一一對應(yīng)的。在Struts中就是通過ActionForm把用戶表單信息提交給控制器。
JSP頁面是經(jīng)典MVC中主要的視圖組件,主要是信息顯示和控制器處理結(jié)果顯示的功能。
除了以上,struts還提供了一個(gè)強(qiáng)大的struts標(biāo)簽庫,來幫助用戶解決顯示邏輯,并且利用ActonForm組件將信息傳遞到控制層。
(2)控制器(Controller)
在控制層,struts提供了一個(gè)控制器組件ActionServlet,它繼承自HttpServlet,并重載了HttpServlet的doGet(),doPost()方法,可以接受HTTP的響應(yīng),并進(jìn)行轉(zhuǎn)發(fā),同時(shí)還提供了使用XML進(jìn)行轉(zhuǎn)發(fā)Mapping(映射)的功能。
(3)模型(Model)
模型表示狀態(tài)和業(yè)務(wù)邏輯的處理,在一般的web應(yīng)用程序中,用JavaBean或者EJB來實(shí)現(xiàn)系統(tǒng)的業(yè)務(wù)邏輯。在Struts中,struts提供Action對象,來管理業(yè)務(wù)邏輯的調(diào)用,幫助用戶分離業(yè)務(wù)邏輯,也就是說struts本身不實(shí)現(xiàn)業(yè)務(wù)邏輯,但可以調(diào)用已完成的業(yè)務(wù)邏輯。
Struts工作流程如下(圖1.2)所示。
圖1.2
ActionServlet是struts中核心的控制器,所有的用戶請求都必須通過ActionServlet的處理,而struts-config.xml是struts中核心的配置文件,在這個(gè)文件中配置了用戶請求URL和控制器Action的映射關(guān)系,ActionServlet通過這個(gè)配置文件把用戶的請求發(fā)送到對應(yīng)的控制器中。
在struts web應(yīng)用程序中,當(dāng)web應(yīng)用程序啟動的時(shí)候,就會初始化ActionServlet在初始化ActionServlet的時(shí)候會加載struts-config.xml配置文件,在加載成功后會把這些URL和控制器映射關(guān)系存放在ActionMapping對象或者其他對象中。當(dāng)ActionServlet接收到用戶請求的時(shí)候,就會按照下面的流程對用戶請求進(jìn)行處理。
(1)ActionServlet接收到用戶的請求后,會根據(jù)請求URL尋找匹配的ActionMapping對象,如果匹配失敗,說明用戶請求的URL路徑信息有誤,所以返回請求路徑無效的信息,當(dāng)找到匹配的ActionMapping的時(shí)候,進(jìn)入到下一步。
(2)當(dāng)ActionServlet找到匹配的ActionMapping對象的時(shí)候,會根據(jù)ActionMapping中的映射信息判斷對應(yīng)的ActionForm對象是否存在,如果不存在對應(yīng)的ActionForm對象就創(chuàng)建一個(gè)新的ActionForm對應(yīng),并把用戶提交的表單信息保存到這個(gè)ActionForm對象中。
(3)在struts-config.xml中這個(gè)配置文件,可以配置表單是否需要驗(yàn)證,如果需要驗(yàn)證,就調(diào)用ActionForm中的validate()方法對用戶輸入的表單進(jìn)行驗(yàn)證。
(4)如果ActionForm的validate()方法返回了ActionErrors對象,則表明驗(yàn)證失敗,ActionServlet把這個(gè)頁面返回到用戶輸入的界面,提示用戶重新輸入。如果方法的返回值為null,就表明驗(yàn)證已經(jīng)通過,可以進(jìn)入下一步處理。
(5)ActionServlet可以根據(jù)ActionMapping對象查找用戶請求轉(zhuǎn)發(fā)給哪個(gè)控制器Action,如果對應(yīng)的Action對象不存在,就創(chuàng)建這個(gè)對象,并調(diào)用這個(gè)Action的excute()方法。
(6)業(yè)務(wù)邏輯控制器Action的execute()方法就會返回一個(gè)ActionForward對象,ActionServlet把控制器處理的結(jié)果轉(zhuǎn)發(fā)到ActionForward對象指定的JSP頁面。
(7)ActionForward對象指定的JSP頁面根據(jù)返回的處理結(jié)果,用合適形式把服務(wù)器處理的結(jié)果展示給用戶,到這里為止,一個(gè)客戶請求的整個(gè)過程完畢。
以上初步struts框架進(jìn)行了介紹,和對原理進(jìn)行了簡單的分析。至于struts是如何實(shí)現(xiàn)MVC的,ActionServlet屬于Controller部分,Action和ActionForm屬于Model層,還是Action屬于Controller層,不同的人對struts有不同的理解。接下來真正的運(yùn)用到實(shí)踐中,在實(shí)踐中深刻去體會,原理固然重要,重要的是運(yùn)用,是能駕馭和使用這個(gè)框架。就像學(xué)習(xí)開車一樣,不是一蹴而就的。