Structs深入研究(一)—–Struts framework的工作原理和組件

來源:互聯網
上載者:User

Struts framework的工作原理和組件

對於Struts 如何控制、處理客戶請求,讓我們通過對struts的四個核心組件介紹來具體說明。這幾個組件就是:ActionServlet。Action Classes,Action Mapping(此處包括ActionForward),ActionFrom Bean。

Struts ActionServlet控制器對象

       ActionServlet繼承自javax.servlet.http.HttpServlet類,其在Struts framework中扮演的角色是中心控制器。它提供一個中心位置來處理全部的終端請求。控制器ActionServlet主要負責將HTTP的客戶請求資訊組裝後,根據設定檔的指定描述,轉寄到適當的處理器。

       按照Servelt的標準,所有得Servlet必須在web設定檔(web.xml)聲明。同樣,ActoinServlet必須在Web Application設定檔(web.xml)中描述,有關配置資訊如下。

<servlet>

<servlet-name>action</servlet-name>

<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

</servlet>

全部的請求URI以*.do的模式存在並映射到這個servlet,其配置如下:

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

一個該模式的請求URI符合如下格式:

             
http://www.my_site_name.com/mycontext/actionName.do

 

中心控制器為所有的展示層請求提供了一個集中的訪問點。這個控制器提供的抽象概念減輕了開發人員建立公用應用系統服務的困難,如管理檢視、會話及表單資料。它也提供一個通用機制如錯誤及異常處理,導航,國際化,資料驗證,資料轉換等。

 

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

Struts Action Classes

      
ActionServlet把全部提交的請求都被控制器委託到RequestProcessor對象。RequestProcessor使用struts-config.xml檔案檢查請求URI找到動作Action標示符。

一個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()方法如何被訪問:

 

Action執行個體的execute()方法

      

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

Struts Action Mapping

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

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

<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>

 

 

<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的申明如下顯示。

使用ActionForward導航

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

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

 

      
ActionForward對象是設定物件。這些設定物件擁有獨一無二的標識以允許它們按照有意義的名稱如“success”,“failure”等來檢索。ActionForward對象封裝了向前進的URL路徑且被要求處理常式用於識別目標視圖。ActionForward對象建立自<forward>元素位於struts-config.xml。下面是一個Struts中<forward>元素例子,屬於<action>元素範圍。

<action path="/editCustomerProfile"

type="packageName.EditCustomerProfileAction"

name="customerProfileForm" scope="request">

<forward name="success" path="/MainMenu.jsp"/>

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

</action>

      
基於執行要求處理常式的execute(…)方法的結果,當傳遞一個值匹配指定於<forward>元素中name屬性的值的時候,下一個視圖可以在execute(…)方法中被開發人員用方便的方法org.apache.struts.action.ActionMapping.findForward(…)選擇。ActionMapping.findForward(…)方法既從它的本地範圍又從全域範圍提供一個ActionForward對象,該對象返回至RequestProcessor以RequestDispatcher.forward(…)或response.sendRedirect(…)調用下一個視圖。當<forward>元素有redirect=“false”屬性或redirect屬性不存在的時候,RequestDispatcher.forward(…)被執行;當redirect=“true”是,將調用sendRedirect(…)方法。下例舉例說明了redirect屬性的用法:

      
  <forward name="success" path="/Catalog.jsp" redirect="true"/>

如果redirect=true, URL建立如/contextPath/path因為HttpServletResponse.sendRedirect(…)中解釋URL採用”/”開頭相對於servlet容器根目錄。

如果redirect=false, URI建立如/path因為ServletContext.getRequestDisptacher(…)採用虛擬目錄相關URL。

 

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

  <global-forwards>

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

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

  </global-forwards>

 

Struts ActionForm Bean捕獲表單資料

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

      
ActionForm派生的對象用於儲存請求對象的參數,因此它們和使用者緊密聯絡。

      
一個ActionForm類被RequestProcessor建立。這是發生在已完成向前進到一個URL,該URL為映射到控制器servlet而不是JSP和相應的動作映射指定的表單屬性的。在這個情況下,如果沒有在指定的活動範圍內找到,RequestProcessor將嘗試尋找可能導致建立一個新ActionForm對象的表單bean。該ActionForm對象在指定的活動範圍內被用<action>元素的name屬性找到;

RequestProcessor將隨後重新安排表單屬性,用請求時參數填充表單,隨即調用表單對象的validate(…)方法以履行伺服器端使用者輸入驗證。僅當ActionMapping對象中validate屬性被設為true時,validate(…)方法被調用;這就是預設的行為。request.getParameterValues(parameterName)被用於得到一個String[]對象,它用來表單填充;驗證的結果應該是一個ActionErrors對象,用org.apache.struts.taglib.html.ErrorsTag來顯示驗證錯誤給使用者。ActionForm也可以被用於為目前使用者儲存即將被一個視圖引用的中間模型狀態。

當一個表單對象被RequestProcessor找到,它被傳遞到要求處理常式的execute(…)方法。一個ActionForm對象也可以被要求處理常式建立。表單對象建立目的是提供中間模型狀態給使用請求範圍JSP;這將確保對象不會在有效性到期後仍然存在。預設的,所有的表單都被儲存為會話範圍。會話中表單對象脫離有效性的存在可能導致浪費記憶體,同樣的,要求處理常式必須跟蹤儲存在會話中的表單對象的生命週期。一個好的捕獲表單資料的實踐是為橫跨多使用者互動的相關表單用一個單獨的表單bean。表單bean也可以在反饋的時候用來儲存能夠被自訂標籤改變的中間模型狀態。在視圖中標籤用法避免結合Java代碼,因此要成一個好的任務劃分,web生產組主要處理標誌,而應用開發組主要處理Java代碼。標籤因素退出訪問中間模型狀態的邏輯;當訪問嵌套的對象或當通過聚集列舉時這個邏輯可能很複雜。

注意:在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()方法。

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

 

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

Struts的其他組件

       Struts framework本身提供了很多可擴充的組件或sub framework,方便的開發人員在其構架上構建web層的應用系統。比如upload,collections ,logging等等。讓我們來看看兩個比較重要的組件:validationg framework和struts taglib。有關其他組件請參考Struts使用者手冊(http://jakarta.apache.org/struts/userGuide)。

      

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。

 

Struts TagLib

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

BeanUtils

       這個組件的全稱是Bean Introspection Utilites。是屬於Jakarta Commons項目組的。主要是協助構建javabean的屬性操作的(getter,setter),已經提供一種動態定義和訪問bean的屬性。有關詳細資料,請參考。

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

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

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

Digester

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

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.