假設現在在有以下情景:使用者正在瀏覽一個用STRUTS的技術構建的網站首頁,首頁上有個登陸表單,使用者填好登陸名和密碼,單擊"登陸"按鈕,就啟用了以下一系列過程:
(1)使用者的請求以HTTP方式傳輸到伺服器上,接受請求的是ActionServlet.
(2)ActionServlet接收到請求後,會尋找Struts-config.xml檔案來確定伺服器上是否有使用者請求的操作,此處使用者請求操作應為登陸操作。如果沒有,則返回一個使用者請求無效的出錯資訊。
(3)當ActionServlet請求找到使用者請求的Action後,首先將使用者輸入的表單參數打包成一個ActionFrom對象,這個ActionFrom對象其實也就是一個JavaBean,裡麵包含兩個欄位,分別是使用者名稱和密碼。接著ActionServlet再根據struts-config.xml中的配置資訊決定是否要執行ActionFrom對象中的Validate方法。若Validate方法執行有錯,則返回。否則,繼續下一步。
(4)系統產生一個使用者所請求的Action的執行個體對象,將前面的ActionFrom對象傳遞給它,運行它的Execute()方法。這一步其實就是使用者登陸的控制器,在執行exectue()方法時,可以調用後台模型驗證登陸名和密碼是否正確等資訊。
(5)execute()執行結束前會產生以和ActionForward類型的對象並將之返回給ActionServlet,該對象的作用是告訴ActionFroward就代表跳轉到一個登陸成功的頁面。ActionServlet將對之進行分析,其實就相當於接收到一個新的請求,重複(2)~(5)的過程,直到將某個介面返會給使用者為止!
以上就是STRUTS的基本工作流程。
更詳細的
struts的流程
Struts controller準系統是
1. 截獲使用者的Http請求
2. 把這個請求映射到一個定義好的業務操作上
3. 擷取業務操作結果,提供給用戶端
4. 決定下一步應該顯示哪一個頁面
有幾個部分共同組成了Struts 的Controller,使用者的請求發送到ActionServlet中,ActionServlet調用RequestProssor開始處理使用者請求的流程,在這個流程中,會尋找ApplicationConfig,得到使用者請求對應的Action,調用相應的Action來具體執行使用者的請求,最後返回ActionForward,轉向相應的流程。
============================================
org.apache.struts.action.ActionServlet 是Struts Controller中最主要的部分,所有使用者請求都會被發送到這裡,所有的其它處理也必須從這裡經過。ActionServlet是從HttpServlet中繼承過來的。
當ActionServlet接收到HTTP request的時候,不管是doGet()或者doPost()方法,都會調用process()方法。
protected void process(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { RequestUtils.selectApplication( request, getServletContext() ); getApplicationConfig(request).getProcessor().process( request, response );}
一般情況下,我們不需要自己實現或者修改ActionServlet類,僅僅使用就可以了。某些情況下,我們可以自己擴充ActionServlet類,從ActionServlet繼承,實現自己的MyActionServlet類。覆蓋其中的一些方法來達到你的特殊處理的需要。ActionServlet繼承自javax.servlet.http.HttpServlet,所以在本質上它和一個普通的servlet沒有區別,你完全可以把它當做一個servlet來看待,只是在其中完成的功能不同罷了。
=============================================
RequestProssor具體處理使用者的request,作為一個request handler存在。同樣,處理request的時候,會執行RequestProcessor類中的process(execute)方法。
process中調用的方法都是可以重載的, 如果有需要,可以實現為自己特定的方法。比如,對於Locale問題,通常都是在系統最一開始載入的時候讀取的,如果使用者想在任何時刻都可以切換或者選擇自己的Locale,我們就可以重載processLocale()方法。然後只需要在設定檔中加入段就可以了
=============================================
Action類是實現整個體系的核心部分,它在客戶請求、介面表示和商務邏輯之間起到一個橋樑的作用。每一個Action都用來處理某一項任務,或者進行一個業務操作。當然了,我們說一項任務不是說Action只實現一個業務操作方法,而是集中實現某一個功能單元。比如登入用的LogonAction、尋找用的SearchAction等等。Action是在RequestProcessor中,由processActionPerform方法調用的
非常重要的一點:不要在Action中包含任何商務邏輯操作,而是應該調用一個Model層的JavaBean來實現你的商務邏輯操作。在某些情況下,可能包含少許表現邏輯。這樣,就可以充分進行代碼重用,比如上例中調用的IStorefrontService介面,這個介面在實現時完全可以不用考慮用戶端的事情,所以它可以被其它部分或者其它系統所使用。否則的話,Action會變得非常難於理解,難於維護,代碼也不能重用。
struts-example工程的設計就是一個bug,它把商務邏輯封裝到了Action類中
=============================================
在Action的execute方法中,返回一個ActionForward類。ActionForward把設定檔中forward部分的資訊封裝起來,減少了應用程式和實體資源資訊之間的耦合性。通過ActionMapping類,可以在設定檔中尋找相應的forward資訊。例如,對於一個LoginAction,它的配置資訊可能是這樣的:
返回的ActionForward就會包含段中的資訊。在ActionMapping類的findForward方法中,首先會根據尋找forward的name尋找是否有相應的forward段,如果沒有,則在設定檔中的段中進行尋找,如果還沒有就會拋出一個例外。
=============================================
以前,頁面上的輸入資料都通過HTTP request提交,服務方檢索出輸入的資料,進行驗證,然後將這些資料傳遞給其它組件進行業務處理。一切基本都需要手工編寫代碼進行操作,比較麻煩,也使代碼變得複雜。
Actionform[org.apache.struts.action.Actionform]用來收集使用者的輸入,並且把這些資訊傳遞給Action對象,然後,在Action對象中,Actionform中的資料被取出來傳遞給商務邏輯層進行處理。
Actionform一方面作為一個緩衝區,臨時儲存使用者輸入的資料;另一方面,可以把Actionform當成是HTTP和Action之間的一個防火牆,它可以驗證輸入資料的正確性,如果驗證不通過,這個request是不會發送給Action進行處理的。
Actionform可以有兩種Scope,request或者session。request就是只能在rquest到response,之後Actionform就不可見了;session可以儲存時間長一點。
=============================================
在Actionform的Validate方法中返回的是ActionErrors對象。這個對象可以將錯誤資訊都封裝起來,並且自動把它們顯示給使用者。
在相應JSP頁面上添加,可以自動將ActionErrors中的錯誤資訊顯示出來。包括,每一個具體的,通過add添加的錯誤資訊,和一個ErrorHeader和一個ErrorFooter,這些都可以通過設定檔指定,並且可以包含HTML文法。
=============================================
Struts提供了四種自訂Tag庫:
bean:struts-bean taglib包含在訪問bean和bean屬性時使用的tag,也包含一些訊息顯示的tag。
html:struts-html taglib包含用來建立struts輸入表單的tag,和其它通常用來建立基於HTML使用者介面的tag。
logic:struts-logic taglib包含的tag用來管理根據條件產生輸出文本,和其它一些用來控制的資訊。
template:struts-template taglib包含的tag用來定義模板機制