ActionServlet主要負責初始化,以及介紹請求并找到合適的RequestRrocessor,之后真正干活的是RequestProecssor和Action.
上回說到ActionServlet的process方法最終會調(diào)用RequestProcessor類的process方法.下面介紹這個方法.
一.RequestProcessor的process方法
public void process(HttpServletRequest request,
1) 調(diào)用processMultipart()方法
如果HTTP請求方式為post,并且contentType為”multipart/form-data”開頭,標準的HttpServletRequest對象將被重新包裝,以方便處理”multipart”類型的HTTP請求.如果請求方式為get,或正congtentType屬性不是”mulitipart”,就直接返回原始的HttpServletRequest對象.
2) 調(diào)用processPath()方法
獲得請求的URI的路徑,這一信息可用于選擇合適的Struts Action組件.
3) 調(diào)用processLocale方法
當ControllerConfig對象的locale屬性為true,將讀取用戶請求中包含的Locale信息,然后把Locale實例保存在session范圍內(nèi).
4) 調(diào)用processContendType(contentType)方法
讀取ControllerConfig對象的conttentType屬性,然后調(diào)用response.setContentType(contentType)方法,設(shè)置響應(yīng)結(jié)果的文檔類型和字符編碼.
processContent()方法如下
5) 調(diào)用processNoCache()方法
讀取ControllerConfig對象的nocache屬性,如果nocache屬性為true,在響應(yīng)結(jié)果中將加入特定的頭參數(shù):Pragma,Cache-Control和Expires,
防止頁面被存儲在客戶的瀏覽器的緩存中,processNoCache方法的代碼如下:
6)調(diào)用processPreprocess()方法
該方法不執(zhí)行任何操作.直接返回true.子類可以覆蓋這個方法.
執(zhí)行客戶化的預(yù)處理請求操作.
7)調(diào)用processMapping()方法
尋找和用戶請求的URI匹配的ActionMapping,如果不存在這樣的ActionMapping,則向用戶返回恰當?shù)腻e誤信息.
8)調(diào)用processRoles()方法
先判斷是否為Action配置了安全角色,如果配置了安全角色,就調(diào)用isUserInRole()方法判斷當前用戶是否具備必需的角色,如果不具備,就結(jié)束請求處理流程.,向用戶返回恰當?shù)腻e誤消息.
9)調(diào)用processActionForm()方法
先判斷是否為ActionMapping配置了ActionForm,如果配置了ActionForm,就先從ActionForm的存在范圍內(nèi)(request或session)尋找改ActionForm實例,如果不存在,就創(chuàng)建一個實例,接下來把它保存在合適的范圍內(nèi),保存時使用的屬性key為ActionMapping的name屬性。
10)調(diào)用processPopulate()方法
如果為ActionMapping配置了ActionForm,就先調(diào)用ActionForm的reset()方法,再把請求中的表單數(shù)據(jù)組裝到ActionForm中。
11)調(diào)用processValidate()方法
如果為ActionMapping配置了ActionForm,并且ActionMapping的validate屬性為true,就調(diào)用ActionForm的validate()方法,如果validate方法返回的ActionErrors對象中包含ActionMessage對象,說明表單驗證失敗。就把ActionErrors對象放在request范圍內(nèi),再把請求轉(zhuǎn)發(fā)到ActionMapping的input屬性指定的Web組件。如果ActionForm的validate方法執(zhí)行表單驗證成功,就繼續(xù)執(zhí)行下面的處理流程。
12)調(diào)用processForward()方法
判斷是否在ActionMapping中配置了forward屬性。如果配置了這個屬性,就調(diào)用RequestDispatcher的forward方法,請求處理流程結(jié)束。否則進行下一步。
13)調(diào)用processInclude()方法
判斷是否在ActionMapping中配置了include屬性。如果配置了這個屬性,就調(diào)用RequestDispatcher的include方法,請求處理流程結(jié)束。否則進行下一步。
14)調(diào)用processActionCreate()方法
先判斷是否在Action緩存中存在這個Action實例,如果沒有就新建一個Action實例,把它放在Action緩存中。可以看出Action也是只有一個實例在運行的。
15)調(diào)用processActionPerform
該方法調(diào)用Action實例的execute方法,該方法位于try/catch中,以及捕獲異常。processActionPerform()方放代碼如下。
16)調(diào)用processActionForward方法
把你的Action的excute方法返回的ActionFoward對象作為參數(shù)傳給它,processActionForward對象包的請求轉(zhuǎn)發(fā)信息來執(zhí)行請求轉(zhuǎn)發(fā)或重定向。
在RequestProcessor類的process方法中,會訪問ControllerConfig、ActionMappig和ActionForward實力的屬性,ControllerConfig類和struts配置文件的<controlle>r元素對應(yīng),ActionMapping類和<action>元素對應(yīng),ActionForward和<forward>元素對應(yīng),process方法通過訪問這三個類實例的屬性來獲得相關(guān)的配置信息。
寫了這么多,RequestProcessor干得事夠多的吧。
二.擴展RequestProcessor類
如果想修改RequestProcessor的一些默認功能,改易覆蓋RequestProcessor基類中的相關(guān)方法.
在struts配置文件中,<controller>元素的processorClass屬性用于配置你自己的RequestProcessor類