天天看點

struts體系結構

Struts 的體系結構 (Struts Framework Architecture) 胡長城(銀狐999) 關鍵字

    Struts,Framework,Architecture,Componennt,MVC

預備知識

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

概述

    本文主要從概念上講解什麼是struts framework,它的架構結構,元件結構,以及簡單的配置講解。對于其應用請參考後面的“struts安裝及應用”和“struts實用案例分析”。

    文章的包括了如下四大部分:

一、             Framework 的概念和體系簡介 (Framework Conception and Architecture) 二、             Struts 的概念和體系結構(Struts Conception and Architecture) 三、             Struts 的工作原理群組件(Struts Componennts) 四、             Struts 配置檔案簡介(Struts Deployment Description) 一、             Framework 概念

一直以來我們都說struts是一個web framework。那麼讓我麼先來看看什麼是Framework。(我想用“架構”一詞來翻譯framework,可是後來越來越發現不太理想和完備,是以就直接用Framework一詞)

Framework概念并不是很新了,伴随着軟體開發的發展,在多層的軟體開發項目中,可重用、易擴充的,而且是經過良好測試的軟體元件,越來越為人們所青睐。這意味着人們可以将充裕的時間用來分析、建構業務邏輯的應用上,而非繁雜的代碼工程。于是人們将相同類型問題的解決途徑進行抽象,抽取成一個應用架構。這也就是我們所說的Framework。

    Framework的體系提供了一套明确機制,進而讓開發人員很容易的擴充和控制整個framework開發上的結構。 通常,framework的結構中都有一個“指令和控制”元件("command and control" component)——Framework Factory and Manager。

圖檔(2):Framework體系

       通過基于請求響應(Request-Response)模式的應用framework,基本上有如下幾個表現邏輯結構組成。

       (1)

控制器

(Controller)——控制整個framework中各個元件的協調工作。

       (2)

業務邏輯層

(Business Logic)——這是framework所希望解決問題的關鍵。當然對framwork本身來說,這裡僅僅隻是概念和幾個提夠服務的基礎元件,真正的實作與客戶的業務邏輯接軌,還需要開發人員在framework上再次擴充。

       (3)

資料邏輯層

(Data Logic)——絕大應用系統都需要涉及到資料互動,這一層次主要包括了資料邏輯和資料通路接口。對于資料邏輯來說,如果你了解資料模組化(Data Modeling)可能就很容易了解。

       下面就進入我們的正題——Struts的結構

二、        Struts 的概念和體系結構

Struts有一組互相協作的類(元件)、Serlvet以及jsp tag lib組成。基于struts構架的web應用程式基本上符合JSP Model2的設計标準,可以說是MVC設計模式的一種變化類型。根據上面對framework的描述,我們很容易了解為什麼說Struts是一個web framwork,而不僅僅是一些标記庫的組合。但 Struts 也包含了豐富的标記庫和獨立于該架構工作的實用程式類。

Struts有其自己的控制器(Controller),同時整合了其他的一些技術去實作模型層(Model)和視圖層(View)。在模型層,Struts可以很容易的與資料通路技術相結合,包括EJB,JDBC和Object Relation Bridge。在視圖層,Struts能夠與JSP, Velocity Templates,XSL等等這些表示層元件想結合。

2.1 Struts 的與Web App的關系

既然struts叫做web framework,那麼其肯定主要基于web層的應用系統開發。按照J2EE Architecture的标準,struts應當和jsp/servlet一樣,存在于web container一層。如圖檔(3)所顯示

圖檔(3): Struts與WebApp的關系 2.2 Struts 的體系結構

    我們說struts framework是MVC 模式的展現,下面我們就從分别從模型、視圖、控制來看看struts的體系結構(Architecture)。圖檔(4)顯示了struts framework的體系結構響應客戶請求時候,各個部分工作的原理。

圖檔(4):Struts體系結構 2.2.1 從視圖角度(View)

    主要由JSP建立,struts自身包含了一組可擴充的自定義标簽庫(TagLib),可以簡化建立使用者界面的過程。目前包括:Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags 這幾個Taglib。有關它們的詳細資料請參考struts使用者手冊

2.2.2 從模型角度(Model)

模型主要是表示一個系統的狀态(有時候,改變系統狀态的業務邏輯操作也也劃分到模型中)。在Struts中,系統的狀态主要有ActiomForm Bean展現,一般情況下,這些狀态是非持久性的。如果需要将這些狀态轉化為持久性資料存儲,Struts本身也提供了Utitle包,可以友善的與資料庫操作

2.2.3 從控制器角度(Controller)

    在Struts framework中, Controller主要是ActionServlet,但是對于業務邏輯的操作則主要由Action、ActionMapping、ActionForward這幾個元件協調完成(也許這幾個元件,應該劃分到模型中的業務邏輯一塊)。其中,Action扮演了真正的業務邏輯的實作者,而ActionMapping和ActionForward則指定了不同業務邏輯或流程的運作方向。

2.3 Struts 的基本元件包

整個struts大約有15包,近200個類所組成,而且數量還在不斷的擴充。在此我們不能一一介紹,隻能列舉幾個主要的簡要的介紹一下。下表說明了目前struts api中基本的幾個元件包,包括action,actions,config,util,taglib,validator。圖檔(5)則顯現了這幾個元件包之間的關系。其中action是整個struts framework的核心

org.apache.struts.action
基本上,控制整個struts framework的運作的核心類、元件都在這個包中,比如我們上面提到的控制器ActionServlet。已經Action,ActionForm,ActionMapping等等。struts1.1比1.0多了 DynaActionForm 類。增加了動态擴充生成FormBean功能
org.apache.struts.actions
這個包是主要作用是提供客戶的http請求和業務邏輯處理之間的特定擴充卡轉換功能,而1.0版本中的部分動态增删FromBean的類,也在struts1.1中被Action包的DynaActionForm元件所取代
org.apache.struts.config
提供對配置檔案struts-config.xml元素的映射。這也是sturts1.1中新增的功能
org.apache.struts.util

Strtuts為了更好支援web application的應用,體統了一個些常用服務的支援,比如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這幾個用于建構使用者界面的标簽類。
org.apache.struts.validator
Struts1.1 framework中增加了validator framework,用于動态的配置from表單的驗證。詳細資訊請參閱 http://home.earthlink.net/~dwinterfeldt/
圖檔(5 ): Struts 的基本元件關系圖

三、

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的客戶請求資訊組裝後,根據配置檔案的指定描述,轉發到适當的處理器。(在Struts1.1中新增了org.apache.struts.action.Action.RequestProcessor類,将處理請求的功能從控制器功能中分離。

    按照Servelt的标準,所有得Servlet必須在web配置檔案(web.xml)聲明。同樣,ActoinServlet必須在Web Application配置檔案(web.xml)中描述,有關配置資訊,後面将會介紹。

當使用者向伺服器端送出請求的時候,實際上資訊是首先發送到控制器ActionServlet,一旦控制器獲得了請求,其就會将請求資訊傳交給一些輔助類(help classes)處理。這些輔助類知道如何去處理與請求資訊所對應的業務操作。在Struts中,這個輔助類就是org.apache.struts.action.Action。通常開發者需要自己繼承Aciton類,進而實作自己的Action執行個體。

3.2 Struts Action Classes

一個Action 類的角色,就像客戶請求動作和業務邏輯處理之間的一個擴充卡(Adaptor),其功能就是将請求與業務邏輯分開。這樣的分離,使得客戶請求和Action類之間可以有多個點對點的映射。而且Action類通常還提供了其它的輔助功能,比如:認證(authorization)、日志(logging)和資料驗證(validation)。

public ActionForward execute(ActionMapping mapping,
              
                             ActionForm form,
              
                             javax.servlet.ServletRequest request,
              
                             javax.servlet.ServletResponse response)
              
                      throws java.io.IOException,javax.servlet.ServletException
              

     Action最為常用的是execute()方法。(注意,以前的perform方法在struts1.1中已經不再支援),還有一個execute()方法,請參考apidoc,在此不在說明。

    當Controller收到客戶的請求的時候,在将請求轉移到一個Action執行個體時,如果這個執行個體不存在,控制器會首先建立,然後會調用這個Action執行個體的execute()方法。Struts Framework為應用系統中的每一個Action類隻建立一個執行個體。因為所有的使用者都使用這一個執行個體,是以你必須确定你的Action 類運作在一個多線程的環境中。下圖顯示了一個execute()方法如何被通路:

圖檔(6 ): Action 執行個體的execute() 方法

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

3.3 Struts Action Mapping

上面講到了一個客戶請求是如何被控制器轉發和處理的,但是,控制器如何知道什麼樣的資訊轉發到什麼樣的Action類呢?這就需要一些與動作和請求資訊相對應的映射配置說明。在struts 中,這些配置映射資訊是存儲在特定的XML檔案(比如struts-config.xml)。 

<action-mappings>

  <action  path="/logonAction"

           type="com.test.LogonAction"

           name="LogonForm"

           scope="request"

           input="logoncheck.jsp"

validate="false">

<forward name="welcome" path="/welcome.jsp"/>

<forward name="failure" path="/logon_failure.jsp "/>

</action>

</action-mappings>

這些配置資訊在系統啟動的時候被讀入記憶體,供struts framework在運作期間使用。在記憶體中,每一個<action>元素都與org.apache.struts.action.ActionMapping類的一個執行個體對應。下表就顯示了一個登陸的配置映射。

<form-beans>

  <form-bean  name="LoginForm"

type="com.test.LoginForm"/>

</form-beans>

上面的配置表示:當可以通過/logonAction.do(此處假設配置的控制器映射為*.do)送出請求資訊的時候,控制器将資訊委托com.test.LogonAction處理。調用LogonAction執行個體的execute()方法。同時将Mapping執行個體和所對應的LogonForm Bean資訊傳入。其中name=LogonForm,使用的form-bean元素所聲明的ActionForm Bean。有關form-bean的申明如下顯示。

元素<forward>則表示了當Action執行個體的execute()方法運作完畢或,控制器根據Mapping可将響應資訊轉到适當的地方。如上面現實,如果客戶登陸成功,則調用welcome forward,将成功資訊傳回到/welcome.jsp頁面。在你的execute()方法的結尾可以使用下面的執行個體代碼而傳回welcome forward。當然你的welcome forward必須在action元素屬性中定義,正如上面所聲明的那樣。

return (mapping.findForward("welcome"));

在此稍稍說一下有關global-forwards的概念。其在配置檔案中描述了整個應用系統可以使用的ActionForward,而不是僅僅是一個特定的Action。

  <global-forwards>

    <forward name="logout" path="/logout.do"/>

<forward name="error"  path="/error.jsp"/>

  </global-forwards>

3.4 Struts ActionForm Bean

在上面講解ActionServlet,Action Classes和Action Mapping的時候,我們都提到了ActionForm Bean的概念。一個應用系統的消息轉移(或者說狀态轉移)的非持久性資料存儲,是由ActionForm Bean的負責保持的。

ActionForm的主要功能就是為Action的操作提供與客戶表單相映射的資料(如果在客戶指定的情況下,還包括對資料進行校驗)。Action負責對系統資料狀态的保持,而Action則負責根據業務邏輯的需要,對資料狀态進行修改,在改變系統狀态後,ActionForm則自動的回寫新的資料狀态并保持。

注意:在struts1.1中,ActionForm的校驗功能,逐漸被剝離出來(當然依然可以使用)。使用了validator framework對整個應用系統的表單資料驗證進行統一管理。相信資訊請參考:http://home.earthlink.net/~dwinterfeldt

在ActionForm的使用中,Struts提倡使用到值對象(Value Object)。這樣将客戶或開發人員,對資料狀态與對象狀态能夠更加清晰的了解和使用。

對于每一個客戶請求,Struts framework在處理ActionForm的時候,一般需要經曆如下幾個步驟:

(1)檢查Action的映射,确定Action中已經配置了對ActionForm的映射

    (2)根據name屬性,查找form bean的配置資訊

    (3)檢查Action的formbean的使用範圍,确定在此範圍下,是否已經有此form bean的執行個體。

    (4)假如目前範圍下,已經存在了此form bean的執行個體,而是對目前請求來說,是同一種類型的話,那麼就重用。

    (5)否則,就重新建構一個form bean的執行個體

    (6)form bean的reset()方法備調用

    (7)調用對應的setter方法,對狀态屬性指派

    (8)如果validatede的屬性北設定為true,那麼就調用form bean的validate()方法。

注意:直接從ActionFrom類繼承的reset()和validate()方法,并不能實作什麼處理功能,是以有必要自己重新覆寫。

如果validate()方法沒有傳回任何錯誤,控制器将ActionForm作為參數,傳給Action執行個體的execute()方法并執行。

       有必要提一下有關org.apache.struts.action.DynaActionForm。這是struts1.1新增的特性。其繼承自ActionForm,在struts早先版本中,我們必須人為的構造特定的ActionFrom子類,但是利用DynaActionForm,可以依據屬性集而動态的建立from bean。有關其詳細資料,請參考···

四、Struts的其他元件

Struts framework本身提供了很多可擴充的元件或sub framework,友善的開發人員在其構架上建構web層的應用系統。比如upload,collections ,logging等等。讓我們來看看兩個比較重要的元件:validationg framework和struts taglib。有關其他元件請參考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資料送出的驗證。将原本需要在ActionFrom Bean的validate()進行的驗證通過配置檔案的描述進行驗證。

有關其詳細資訊,請參考http://home.earthlink.net/~dwinterfeldt 。個人建議對于小型應用系統可以采用這種配置方式,但是對于應用系統中有大量web層表單應用的系統,并且業務需求變動比較大的,使用validation framework 可能會加重開發難度、系統維護難度。可以借鑒validation framework的Javascript Validator Tag。

4.2 Struts TagLib

    struts提供了一組可擴充的自定義标簽庫(TagLib),可以簡化建立使用者界面的過程。目前包括:Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags 這幾個Taglib。有關Struts Taglib的結構和使用,可以參考前面有關Cutomer Tag Lib的介紹,有關起詳細資料,請參考

4.3 BeanUtils

    這個元件的全稱是Bean Introspection Utilites。是屬于Jakarta Commons項目組的。主要是幫助建構javabean的屬性操作的(getter,setter),已經提供一種動态定義和通路bean的屬性。有關詳細資訊,請參考。

http://jakarta.apache.org/commons/beanutils.html

    如果各位對這方面有很興趣,可以參考一些有關java反射(Reflectio)方面的資料。

4 .4 Collections

    這個元件主要是提供了一些集合或清單對象,在原有的java collections framework的基礎上進行了擴充。詳細資料請參考:

http://jakarta.apache.org/commons/collections.html 以及

http://cvs.apache.org/viewcvs/~checkout~/jakarta-commons/collections/STATUS.html?rev=1.13

4 .5 Digester

    這個元件翻譯成中文的意思是“彙編”。其主要功能是根據xml配置檔案,初始化系統的一些java類對象。Digester幫助你指定XML與java對象之間映射模型,而且允許客戶話定制映射規則(rules)。詳細資料請參考

http://jakarta.apache.org/commons/digester.html

4 .6 其他相關元件

    由于篇幅問題,還有一些元件就不一一介紹了,包括Database Connection Pool,Upload,Logging,Pool,Services。基在struts使用者手冊都有詳細介紹,請參考。

五、 Struts配置檔案簡介( Deployment Description

struts framework根據配置檔案指定(更确切的說,是控制器),才使得ServletAction,ActionMapping,Action , ActionForm這幾個不同層次的元件互相互動,協調的工作。前面也提到了,這些配置檔案是在系統啟動的時候,讀入導記憶體中,供控制器使用的。

Struts framework主要包括三部分的配置描述,一個是指定有關Struts Controller及其相關的的配置描述(Initialization Parameters),一個時對struts tag lib的描述,一個是struts元件(ActionMapping,Action,ActionForm)之間互相映射協調的關系

5.1 有關Struts Controller及其相關的的配置描述

    因為Struts Controller的主要類ActionServlet是繼承自HttpServlet,是以必須像配置一個Servlet那樣配置ActionServlet類及其通路映射。詳細資訊請參考:

http://jakarta.apache.org/struts/userGuide/building_controller.html#dd_config

5.2 有關struts tag lib的配置描述

    如果你的web application打算使用Struts的taglib,那麼你有必要在web.xml中對struts taglib進行配置描述。有關詳細的描述和說明請參考

http://jakarta.apache.org/struts/userGuide/building_controller.html#dd_config_taglib

5.3 有關Struts Action Mapping的配置描述

    Struts本身有一個配置檔案,通常情況為struts-config.xml。有關其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

    有關詳細資訊請參閱

http://jakarta.apache.org/struts/userGuide/building_controller.html#config

    有必要提一下的是,在struts1.1中,提出了對Multiple Application Support。在struts的早先版本中,隻有一個struts配置檔案,一般叫struts-config.xml。但是,對于越來越複雜的應用系統的發展,隻有一個地方存放這個一個檔案,對大型項目來說,使用和修改這個配置檔案,使其成為了一個應用的瓶頸問題。在struts1.1中,你可以定義多了配置檔案協同工作。

總結

    希望通過以上的對Struts Framework的講解,讀者可以對Struts的整體結構有個比較清晰的認識,對其如何處理客戶請求,如何進行業務邏輯的處理和自動流轉能夠有個概念上的認識。

Resource

① Struts的官方網站:

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

繼續閱讀