標籤:style http color java os io 檔案 資料
RequestProcessor
ActionServlet是Struts架構裡唯一一個Servlet,它負責處理所有請求。它無論何時收到一個請求,都會首先試著為現有請求找到一個子應用。一旦子應用被找到,它會為其產生一個RequestProcessor對象,並調用傳入HttpServletRequest和HttpServletResponse為參數的process()方法。
一、RequestProcessor.process()
java代碼:
public void process(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException {//如果HttpServletRequest是POST方式,且請求為multipart/form-data //Struts架構將請求對象封裝成處理multipart 請求專用的請求對象,否則,只是簡單地返回原有的請求對象request = processMultipart(request);//該方法用來從請求URI中獲應用取路徑部分。擷取到的資訊在稍後的步驟中用於選擇合適的Struts Action調用。String path = processPath(request, response);if (path == null) {return;}if (log.isDebugEnabled()) {log.debug("Processing a '" + request.getMethod() + "' for path '"+ path + "'");}//處理一些國際化的事務processLocale(request, response);//來決定請求的content type編碼(encoding)方式processContent(request, response);//根據noCache屬性的設定調用processNoCache() 方法,//如果noCache設定為true。則添加合適的回應標頭到響應對象中,使得頁面保留在瀏覽器的Cache中processNoCache(request, response);// General purpose preprocessing hook//這個方法在這兒設定一個鉤子,方法的預設實現只是簡單地返回true,//這樣給了自訂處理器的開發人員提供了一個合適的地方讓你添加自己的商務邏輯。//因為這個方法在調用Action之前被調用,如果你重載這個方法,只需要返回false,則Action就不會被調用if (!processPreprocess(request, response)) {return;}this.processCachedMessages(request, response);// Identify the mapping for this request//根據客戶請求資訊中的path資訊來決定是否返回ActionMapping對象執行個體。//如果不能夠找到path 的映射,則客戶將會得到一個error 響應。 ActionMapping mapping = processMapping(request, response, path);if (mapping == null) {return;}// Check for any role required to perform this action//檢查是否為Action配置了資訊安全角色。//如果配置了角色要求,則請求對象的isUserInRole()方法被調用,//如果使用者屬於這些角色,則客戶會得到顯示一個error 響應。 if (!processRoles(request, response, mapping)) {return;}// Process any ActionForm bean related to this request//檢查是否存在為ActionMapping配置的ActionForm 。//如果存在,則在有效地區內尋找是否存在該ActionForm 的執行個體,存在,則複用,不存在,則建立一個執行個體。//然後將執行個體儲存與再設定檔中配置好的有效地區(request,session,application)內,//並用Action元素的name屬性作為該執行個體的關鍵字。 ActionForm form = processActionForm(request, response, mapping);//如果存在為ActionMapping配置的ActionForm,//則封裝請求對象中的資料到ActionForm 中,//在進行封裝之前,先調用ActionForm 的reset()方法進行屬性值的預設化。 processPopulate(request, response, form, mapping);// Validate any fields of the ActionForm bean, if applicable//如果ActionForm被配置好,並且action元素的屬性validate被設定為true ,//則進一步調用validate()方法進行規則校正。//如果validate()方法校正失敗,就會儲存一個ActionErrors 對象到請求地區中,//請求將會自動重新導向到action映射的input屬性所指定的頁面中。//如果校正通過或在action 映射中沒有配置ActionForm,則繼續處理請求。 try {if (!processValidate(request, response, form, mapping)) {return;}} catch (InvalidCancelException e) {ActionForward forward = processException(request, response, e,form, mapping);processForwardConfig(request, response, forward);return;} catch (IOException e) {throw e;} catch (ServletException e) {throw e;}//根據action 映射是否配置了forward屬性或include屬性來決定下一步操作。//如果配置了任意一個,則相應地調用RequestDispatcher對象的forward()方法或include()方法,//調用後,對客戶請求的處理結束。否則,繼續處理請求。 // Process a forward or include specified by this mappingif (!processForward(request, response, mapping)) {return;}if (!processInclude(request, response, mapping)) {return;}//建立或擷取一個Action對象執行個體處理請求。//processActionCreate()方法會在緩衝中尋找是否存在已經建立好的Action執行個體,//如果存在,則複用,否則,則重新建立並將其村於緩衝中。 Action action = processActionCreate(request, response, mapping);if (action == null) {return;}// Call the Action instance itself//該方法用於在一個try/catch 代碼塊中調用action 執行個體的execute()方法,//這樣確保action 的execute()方法一旦發生執行異常能夠被RequestProcessor捕獲。 ActionForward forward = processActionPerform(request, response, action,form, mapping);// Process the returned ActionForward instance//通過檢查ActionForward對象執行個體,決定採用redirect或forword方式進行重新導向。究竟採用redirect還是 //forword取決於forward元素的redirect屬性值。processForwardConfig(request, response, forward);}
二、擴充RequestProcessor類
如果想修改RequestProcessor的一些預設功能,改易覆蓋RequestProcessor基類中的相關方法.
Java代碼
Public classCustomRequestProcessor extends RequestProcessor{ protected void processPreprocess(HttpServletRequest request, HttpServletResponse response) { request.setCharacterEncoding("UTF-8"); //在這加一行設定編碼的的代嗎。 super.process(request, response);} }
在struts設定檔中,<controller>元素的processorClass屬性用於配置你自己的RequestProcessor類
<controller contentType=“text/html:charset=”GB2312” locale=”true”nocache=”true” processorCalss=”com.test.CustomRequestProcessor”/>
總結
大部分請處理都是在RequestProcessor.process()發生的。Process()方法是以模板方法(TemplateMethod)的設計模式來實現的,其中有完成request處理的每個步驟的方法;所有這些方法都從process()方法順序調用。例如,尋找當前請求的ActionForm類和檢查目前使用者是否有許可權執行actionmapping都有幾個單獨的方法。這給我們提供了極大的彈性空間。Struts的RequestProcessor對每個請求處理步驟都提供了預設的實現方法。這樣就可以重寫需要的方法,而其餘剩下的保留預設實現。