Sung in Blog

                     一些技術(shù)文章 & 一些生活雜碎

          自學

          預(yù)備知識
          在開始學習Struts以前,以下的知識點,需要有所了解: 模型-視圖-控制的軟件構(gòu)架模式,JSP/Servlet的web層應(yīng)用,J2EE體系結(jié)構(gòu)。如果對客戶標簽類(Customer TagLib)有所了解也許更容易理解Struts本身的TagLib。

          概述
          本文主要從概念上講解什么是struts framework,它的框架結(jié)構(gòu),組件結(jié)構(gòu),以及簡單的配置講解。對于其應(yīng)用請參考后面的“struts安裝及應(yīng)用”和“struts實用案例分析”。
          文章的包括了如下四大部分:
          一、 Framework的概念和體系簡介 (Framework Conception and Architecture)
          二、 Struts的概念和體系結(jié)構(gòu)(Struts Conception and Architecture)
          三、 Struts的工作原理和組件(Struts Componennts)
          四、 Struts配置文件簡介(Struts Deployment Description)

          一、 Framework概念
          一直以來我們都說struts是一個web framework。那么讓我么先來看看什么是Framework。(我想用“框架”一詞來翻譯framework,可是后來越來越發(fā)現(xiàn)不太理想和完備,所以就直接用Framework一詞)
          Framework概念并不是很新了,伴隨著軟件開發(fā)的發(fā)展,在多層的軟件開發(fā)項目中,可重用、易擴展的,而且是經(jīng)過良好測試的軟件組件,越來越為人們所青睞。這意味著人們可以將充裕的時間用來分析、構(gòu)建業(yè)務(wù)邏輯的應(yīng)用上,而非繁雜的代碼工程。于是人們將相同類型問題的解決途徑進行抽象,抽取成一個應(yīng)用框架。這也就是我們所說的Framework。
          Framework的體系提供了一套明確機制,從而讓開發(fā)人員很容易的擴展和控制整個framework開發(fā)上的結(jié)構(gòu)。 通常,framework的結(jié)構(gòu)中都有一個“命令和控制”組件("command and control" component)??Framework Factory and Manager。

          圖片(2):Framework體系


          通過基于請求響應(yīng)(Request-Response)模式的應(yīng)用framework,基本上有如下幾個表現(xiàn)邏輯結(jié)構(gòu)組成。
          (1)控制器(Controller)??控制整個framework中各個組件的協(xié)調(diào)工作。
          (2)業(yè)務(wù)邏輯層(Business Logic)??這是framework所希望解決問題的關(guān)鍵。當然對framwork本身來說,這里僅僅只是概念和幾個提夠服務(wù)的基礎(chǔ)組件,真正的實現(xiàn)與客戶的業(yè)務(wù)邏輯接軌,還需要開發(fā)人員在framework上再次擴展。
          (3)數(shù)據(jù)邏輯層(Data Logic)??絕大應(yīng)用系統(tǒng)都需要涉及到數(shù)據(jù)交互,這一層次主要包括了數(shù)據(jù)邏輯和數(shù)據(jù)訪問接口。對于數(shù)據(jù)邏輯來說,如果你了解數(shù)據(jù)建模(Data Modeling)可能就很容易理解。

          下面就進入我們的正題??Struts的結(jié)構(gòu)

          二、 Struts的概念和體系結(jié)構(gòu)
          Struts有一組相互協(xié)作的類(組件)、Serlvet以及jsp tag lib組成。基于struts構(gòu)架的web應(yīng)用程序基本上符合JSP Model2的設(shè)計標準,可以說是MVC設(shè)計模式的一種變化類型。根據(jù)上面對framework的描述,我們很容易理解為什么說Struts是一個web framwork,而不僅僅是一些標記庫的組合。但 Struts 也包含了豐富的標記庫和獨立于該框架工作的實用程序類。
          Struts有其自己的控制器(Controller),同時整合了其他的一些技術(shù)去實現(xiàn)模型層(Model)和視圖層(View)。在模型層,Struts可以很容易的與數(shù)據(jù)訪問技術(shù)相結(jié)合,包括EJB,JDBC和Object Relation Bridge。在視圖層,Struts能夠與JSP, Velocity Templates,XSL等等這些表示層組件想結(jié)合。

          2.1 Struts的與Web App的關(guān)系

          既然struts叫做web framework,那么其肯定主要基于web層的應(yīng)用系統(tǒng)開發(fā)。按照J2EE Architecture的標準,struts應(yīng)當和jsp/servlet一樣,存在于web container一層。如圖片(3)所顯示
          圖片(3): Struts與WebApp的關(guān)系

          2.2 Struts的體系結(jié)構(gòu)
          我們說struts framework是MVC 模式的體現(xiàn),下面我們就從分別從模型、視圖、控制來看看struts的體系結(jié)構(gòu)(Architecture)。圖片(4)顯示了struts framework的體系結(jié)構(gòu)響應(yīng)客戶請求時候,各個部分工作的原理。
          圖片(4):Struts體系結(jié)構(gòu)

          2.2.1從視圖角度(View)
          主要由JSP建立,struts自身包含了一組可擴展的自定義標簽庫(TagLib),可以簡化創(chuàng)建用戶界面的過程。目前包括:Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags 這幾個Taglib。有關(guān)它們的詳細資料請參考struts用戶手冊
          2.2.2從模型角度(Model)
          模型主要是表示一個系統(tǒng)的狀態(tài)(有時候,改變系統(tǒng)狀態(tài)的業(yè)務(wù)邏輯操作也也劃分到模型中)。在Struts中,系統(tǒng)的狀態(tài)主要有ActiomForm Bean體現(xiàn),一般情況下,這些狀態(tài)是非持久性的。如果需要將這些狀態(tài)轉(zhuǎn)化為持久性數(shù)據(jù)存儲,Struts本身也提供了Utitle包,可以方便的與數(shù)據(jù)庫操作
          2.2.3 從控制器角度(Controller)
          在Struts framework中, Controller主要是ActionServlet,但是對于業(yè)務(wù)邏輯的操作則主要由Action、ActionMapping、ActionForward這幾個組件協(xié)調(diào)完成(也許這幾個組件,應(yīng)該劃分到模型中的業(yè)務(wù)邏輯一塊)。其中,Action扮演了真正的業(yè)務(wù)邏輯的實現(xiàn)者,而ActionMapping和ActionForward則指定了不同業(yè)務(wù)邏輯或流程的運行方向。

          2.3 Struts的基本組件包
          整個struts大約有15包,近200個類所組成,而且數(shù)量還在不斷的擴展。在此我們不能一一介紹,只能列舉幾個主要的簡要的介紹一下。下表說明了目前struts api中基本的幾個組件包,包括action,actions,config,util,taglib,validator。圖片(5)則顯現(xiàn)了這幾個組件包之間的關(guān)系。其中action是整個struts framework的核心
          org.apache.struts.action
          基本上,控制整個struts framework的運行的核心類、組件都在這個包中,比如我們上面提到的控制器ActionServlet。已經(jīng)Action,ActionForm,ActionMapping等等。struts1.1比1.0多了 DynaActionForm 類。增加了動態(tài)擴展生成FormBean功能
          org.apache.struts.actions
          這個包是主要作用是提供客戶的http請求和業(yè)務(wù)邏輯處理之間的特定適配器轉(zhuǎn)換功能,而1.0版本中的部分動態(tài)增刪FromBean的類,也在struts1.1中被Action包的DynaActionForm組件所取代
          org.apache.struts.config
          提供對配置文件struts-config.xml元素的映射。這也是sturts1.1中新增的功能
          org.apache.struts.util
          Strtuts為了更好支持web application的應(yīng)用,體統(tǒng)了一個些常用服務(wù)的支持,比如Connection Pool和Message Source。詳細信息請參考http://jakarta.apache.org/struts/api/org/apache/struts/util/package-summary.html
          org.apache.struts.taglib
          這不是一個包,而是是一個客戶標簽類的集合。下面包括Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags這幾個用于構(gòu)建用戶界面的標簽類。
          org.apache.struts.validator
          Struts1.1 framework中增加了validator framework,用于動態(tài)的配置from表單的驗證。詳細信息請參閱 http://home.earthlink.net/~dwinterfeldt/








          三、 Struts framework的工作原理和組件
          對于Struts 如何控制、處理客戶請求,讓我們通過對struts的四個核心組件介紹來具體說明。這幾個組件就是:ActionServlet。Action Classes,Action Mapping(此處包括ActionForward),ActionFrom Bean。
          3.1 Struts ActionServlet
          ActionServlet繼承自javax.servlet.http.HttpServlet類,其在Struts framework中扮演的角色失控制器,參看上面的“Struts體系圖”。控制器ActionServlet主要負責將HTTP的客戶請求信息組裝后,根據(jù)配置文件的指定描述,轉(zhuǎn)發(fā)到適當?shù)奶幚砥鳌#ㄔ赟truts1.1中新增了org.apache.struts.action.Action.RequestProcessor類,將處理請求的功能從控制器功能中分離。
          按照Servelt的標準,所有得Servlet必須在web配置文件(web.xml)聲明。同樣,ActoinServlet必須在Web Application配置文件(web.xml)中描述,有關(guān)配置信息,后面將會介紹。

          當用戶向服務(wù)器端提交請求的時候,實際上信息是首先發(fā)送到控制器ActionServlet,一旦控制器獲得了請求,其就會將請求信息傳交給一些輔助類(help classes)處理。這些輔助類知道如何去處理與請求信息所對應(yīng)的業(yè)務(wù)操作。在Struts中,這個輔助類就是org.apache.struts.action.Action。通常開發(fā)者需要自己繼承Aciton類,從而實現(xiàn)自己的Action實例。

          3.2 Struts Action Classes
          一個Action 類的角色,就像客戶請求動作和業(yè)務(wù)邏輯處理之間的一個適配器(Adaptor),其功能就是將請求與業(yè)務(wù)邏輯分開。這樣的分離,使得客戶請求和Action類之間可以有多個點對點的映射。而且Action類通常還提供了其它的輔助功能,比如:認證(authorization)、日志(logging)和數(shù)據(jù)驗證(validation)。
          Action最為常用的是execute()方法。(注意,以前的perform方法在struts1.1中已經(jīng)不再支持),還有一個execute()方法,請參考apidoc,在此不在說明。
          當Controller收到客戶的請求的時候,在將請求轉(zhuǎn)移到一個Action實例時,如果這個實例不存在,控制器會首先創(chuàng)建,然后會調(diào)用這個Action實例的execute()方法。Struts Framework為應(yīng)用系統(tǒng)中的每一個Action類只創(chuàng)建一個實例。因為所有的用戶都使用這一個實例,所以你必須確定你的Action 類運行在一個多線程的環(huán)境中。下圖顯示了一個execute()方法如何被訪問:

          圖片(6): Action實例的execute()方法

          注意,客戶自己繼承的Action子類,必須重寫execute()方法,因為Action類在默認情況下是返回null的。


          3.3 Struts Action Mapping
          上面講到了一個客戶請求是如何被控制器轉(zhuǎn)發(fā)和處理的,但是,控制器如何知道什么樣的信息轉(zhuǎn)發(fā)到什么樣的Action類呢?這就需要一些與動作和請求信息相對應(yīng)的映射配置說明。在struts 中,這些配置映射信息是存儲在特定的XML文件(比如struts-config.xml)。
          這些配置信息在系統(tǒng)啟動的時候被讀入內(nèi)存,供struts framework在運行期間使用。在內(nèi)存中,每一個<action>元素都與org.apache.struts.action.ActionMapping類的一個實例對應(yīng)。下表就顯示了一個登陸的配置映射。

          上面的配置表示:當可以通過/logonAction.do(此處假設(shè)配置的控制器映射為*.do)提交請求信息的時候,控制器將信息委托com.test.LogonAction處理。調(diào)用LogonAction實例的execute()方法。同時將Mapping實例和所對應(yīng)的LogonForm Bean信息傳入。其中name=LogonForm,使用的form-bean元素所聲明的ActionForm Bean。有關(guān)form-bean的申明如下顯示。

          元素<forward>則表示了當Action實例的execute()方法運行完畢或,控制器根據(jù)Mapping可將響應(yīng)信息轉(zhuǎn)到適當?shù)牡胤健H缟厦娆F(xiàn)實,如果客戶登陸成功,則調(diào)用welcome forward,將成功信息返回到/welcome.jsp頁面。在你的execute()方法的結(jié)尾可以使用下面的實例代碼而返回welcome forward。當然你的welcome forward必須在action元素屬性中定義,正如上面所聲明的那樣。

          在此稍稍說一下有關(guān)global-forwards的概念。其在配置文件中描述了整個應(yīng)用系統(tǒng)可以使用的ActionForward,而不是僅僅是一個特定的Action。


          3.4 Struts ActionForm Bean
          在上面講解ActionServlet,Action Classes和Action Mapping的時候,我們都提到了ActionForm Bean的概念。一個應(yīng)用系統(tǒng)的消息轉(zhuǎn)移(或者說狀態(tài)轉(zhuǎn)移)的非持久性數(shù)據(jù)存儲,是由ActionForm Bean的負責保持的。
          ActionForm的主要功能就是為Action的操作提供與客戶表單相映射的數(shù)據(jù)(如果在客戶指定的情況下,還包括對數(shù)據(jù)進行校驗)。Action負責對系統(tǒng)數(shù)據(jù)狀態(tài)的保持,而Action則負責根據(jù)業(yè)務(wù)邏輯的需要,對數(shù)據(jù)狀態(tài)進行修改,在改變系統(tǒng)狀態(tài)后,ActionForm則自動的回寫新的數(shù)據(jù)狀態(tài)并保持。
          注意:在struts1.1中,ActionForm的校驗功能,逐漸被剝離出來(當然依然可以使用)。使用了validator framework對整個應(yīng)用系統(tǒng)的表單數(shù)據(jù)驗證進行統(tǒng)一管理。相信信息請參考:http://home.earthlink.net/~dwinterfeldt
          在ActionForm的使用中,Struts提倡使用到值對象(Value Object)。這樣將客戶或開發(fā)人員,對數(shù)據(jù)狀態(tài)與對象狀態(tài)能夠更加清晰的理解和使用。
          對于每一個客戶請求,Struts framework在處理ActionForm的時候,一般需要經(jīng)歷如下幾個步驟:
          (1)檢查Action的映射,確定Action中已經(jīng)配置了對ActionForm的映射
          (2)根據(jù)name屬性,查找form bean的配置信息
          (3)檢查Action的formbean的使用范圍,確定在此范圍下,是否已經(jīng)有此form bean的實例。
          (4)假如當前范圍下,已經(jīng)存在了此form bean的實例,而是對當前請求來說,是同一種類型的話,那么就重用。
          (5)否則,就重新構(gòu)建一個form bean的實例
          (6)form bean的reset()方法備調(diào)用
          (7)調(diào)用對應(yīng)的setter方法,對狀態(tài)屬性賦值
          (8)如果validatede的屬性北設(shè)置為true,那么就調(diào)用form bean的validate()方法。
          注意:直接從ActionFrom類繼承的reset()和validate()方法,并不能實現(xiàn)什么處理功能,所以有必要自己重新覆蓋。
          如果validate()方法沒有返回任何錯誤,控制器將ActionForm作為參數(shù),傳給Action實例的execute()方法并執(zhí)行。


          有必要提一下有關(guān)org.apache.struts.action.DynaActionForm。這是struts1.1新增的特性。其繼承自ActionForm,在struts早先版本中,我們必須人為的構(gòu)造特定的ActionFrom子類,但是利用DynaActionForm,可以依據(jù)屬性集而動態(tài)的創(chuàng)建from bean。有關(guān)其詳細資料,請參考???


          四、Struts的其他組件
          Struts framework本身提供了很多可擴展的組件或sub framework,方便的開發(fā)人員在其構(gòu)架上構(gòu)建web層的應(yīng)用系統(tǒng)。比如upload,collections ,logging等等。讓我們來看看兩個比較重要的組件:validationg framework和struts taglib。有關(guān)其他組件請參考Struts用戶手冊(http://jakarta.apache.org/struts/userGuide)。
          在stuts1.0中有些很不錯的概念和組件,比如benaUtils,Collections等等,后來被Jakarta Commons項目組吸收而獨立處struts framework。但是struts依然需要依賴這些組件才能正常的工作。
          4.1 Validation Framework for Struts
          在struts1.1中,新增了validation framework。增加了對form數(shù)據(jù)提交的驗證。將原本需要在ActionFrom Bean的validate()進行的驗證通過配置文件的描述進行驗證。
          有關(guān)其詳細信息,請參考http://home.earthlink.net/~dwinterfeldt 。個人建議對于小型應(yīng)用系統(tǒng)可以采用這種配置方式,但是對于應(yīng)用系統(tǒng)中有大量web層表單應(yīng)用的系統(tǒng),并且業(yè)務(wù)需求變動比較大的,使用validation framework 可能會加重開發(fā)難度、系統(tǒng)維護難度。可以借鑒validation framework的Javascript Validator Tag。

          4.2 Struts TagLib
          struts提供了一組可擴展的自定義標簽庫(TagLib),可以簡化創(chuàng)建用戶界面的過程。目前包括:Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags 這幾個Taglib。有關(guān)Struts Taglib的結(jié)構(gòu)和使用,可以參考前面有關(guān)Cutomer Tag Lib的介紹,有關(guān)起詳細資料,請參考

          4.3 BeanUtils
          這個組件的全稱是Bean Introspection Utilites。是屬于Jakarta Commons項目組的。主要是幫助構(gòu)建javabean的屬性操作的(getter,setter),已經(jīng)提供一種動態(tài)定義和訪問bean的屬性。有關(guān)詳細信息,請參考。
          http://jakarta.apache.org/commons/beanutils.html
          如果各位對這方面有很興趣,可以參考一些有關(guān)java反射(Reflectio)方面的資料。

          4.4 Collections
          這個組件主要是提供了一些集合或列表對象,在原有的java collections framework的基礎(chǔ)上進行了擴展。詳細資料請參考:
          http://jakarta.apache.org/commons/collections.html 以及
          http://cvs.apache.org/viewcvs/~checkout~/jakarta-commons/collections/STATUS.html?rev=1.13

          4.5 Digester
          這個組件翻譯成中文的意思是“匯編”。其主要功能是根據(jù)xml配置文件,初始化系統(tǒng)的一些java類對象。Digester幫助你指定XML與java對象之間映射模型,而且允許客戶話定制映射規(guī)則(rules)。詳細資料請參考
          http://jakarta.apache.org/commons/digester.html

          4.6 其他相關(guān)組件
          由于篇幅問題,還有一些組件就不一一介紹了,包括Database Connection Pool,Upload,Logging,Pool,Services。基在struts用戶手冊都有詳細介紹,請參考。



          五、 Struts配置文件簡介(Deployment Description)
          struts framework根據(jù)配置文件指定(更確切的說,是控制器),才使得ServletAction,ActionMapping,Action , ActionForm這幾個不同層次的組件相互交互,協(xié)調(diào)的工作。前面也提到了,這些配置文件是在系統(tǒng)啟動的時候,讀入導內(nèi)存中,供控制器使用的。
          Struts framework主要包括三部分的配置描述,一個是指定有關(guān)Struts Controller及其相關(guān)的的配置描述(Initialization Parameters),一個時對struts tag lib的描述,一個是struts組件(ActionMapping,Action,ActionForm)之間相互映射協(xié)調(diào)的關(guān)系

          5.1有關(guān)Struts Controller及其相關(guān)的的配置描述
          因為Struts Controller的主要類ActionServlet是繼承自HttpServlet,所以必須像配置一個Servlet那樣配置ActionServlet類及其訪問映射。詳細信息請參考:
          http://jakarta.apache.org/struts/userGuide/building_controller.html#dd_config

          5.2 有關(guān)struts tag lib的配置描述
          如果你的web application打算使用Struts的taglib,那么你有必要在web.xml中對struts taglib進行配置描述。有關(guān)詳細的描述和說明請參考
          http://jakarta.apache.org/struts/userGuide/building_controller.html#dd_config_taglib

          5.3 有關(guān)Struts Action Mapping的配置描述
          Struts本身有一個配置文件,通常情況為struts-config.xml。有關(guān)其DTD文檔的描述,請參考http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd
          (或struts-config_1_0.dtd)
          一般struts-config(version1.1)包含了如下幾個部分:
          (1)form-bean
          (2)global-forwards
          (3)action-mappings
          (4)data-sources
          有關(guān)詳細信息請參閱
          http://jakarta.apache.org/struts/userGuide/building_controller.html#config

          有必要提一下的是,在struts1.1中,提出了對Multiple Application Support。在struts的早先版本中,只有一個struts配置文件,一般叫struts-config.xml。但是,對于越來越復(fù)雜的應(yīng)用系統(tǒng)的發(fā)展,只有一個地方存放這個一個文件,對大型項目來說,使用和修改這個配置文件,使其成為了一個應(yīng)用的瓶頸問題。在struts1.1中,你可以定義多了配置文件協(xié)同工作。

          總結(jié)
          希望通過以上的對Struts Framework的講解,讀者可以對Struts的整體結(jié)構(gòu)有個比較清晰的認識,對其如何處理客戶請求,如何進行業(yè)務(wù)邏輯的處理和自動流轉(zhuǎn)能夠有個概念上的認識。

          Resource
          ① Struts的官方網(wǎng)站:
          http://jakarta.apache.org/struts/
          ② Struts用戶手冊(User Guide)
          http://jakarta.apache.org/struts/userGuide
          ③ ARTICLE --- Framework save the day
          http://www.javaworld.com/jw-09-2000/jw-0929-ejbframe.html
          ④ ARTICLE --- Building a Java servlet framework using reflection
          http://www.javaworld.com/javaworld/jw-11-1999/jw-11-servlet.html
          ⑤ Validation Framework
          http://home.earthlink.net/~dwinterfeldt/
          http://cvs.apache.org/viewcvs/jakarta-commons/validator/
          ⑥ ARTICLE --- Struts1.1,Should I upgrade?
          http://www.theserverside.com/resources/article.jsp?l=Struts1_1  

          posted on 2005-10-26 16:28 Sung 閱讀(507) 評論(0)  編輯  收藏 所屬分類: Struts
          主站蜘蛛池模板: 常山县| 乌什县| 神木县| 五原县| 东源县| 宕昌县| 成安县| 鄂伦春自治旗| 饶平县| 安顺市| 常山县| 兴国县| 花垣县| 盘锦市| 思茅市| 休宁县| 大港区| 兴宁市| 大洼县| 弥渡县| 繁昌县| 湄潭县| 乾安县| 高要市| 精河县| 沙河市| 五大连池市| 黎平县| 鸡西市| 东安县| 南溪县| 三台县| 同仁县| 昌吉市| 石嘴山市| 定州市| 洛浦县| 遵义县| 九龙县| 滕州市| 多伦县|