本文從收到一個請求開始講述,忽略之前的filter等工作.
處理工作的主要承擔者爲RequestProcessor
1.處理請求的url. RequestProcessor.processPath(request,response)
String path = processPath(request, response);
1 protected String processPath(HttpServletRequest request, 2 HttpServletResponse response) 3 throws IOException { 4 5 String path = null; 6 7 // For prefix matching, match on the path info (if any) 8 path = (String) request.getAttribute(INCLUDE_PATH_INFO); 9 if (path == null) { 10 path = request.getPathInfo(); 11 } 12 if ((path != null) && (path.length() > 0)) { 13 return (path); 14 } 15 16 // For extension matching, strip the module prefix and extension 17 path = (String) request.getAttribute(INCLUDE_SERVLET_PATH); 18 if (path == null) { 19 path = request.getServletPath(); 20 } 21 String prefix = moduleConfig.getPrefix(); 22 if (!path.startsWith(prefix)) { 23 String msg = getInternal().getMessage("processPath"); 24 25 log.error(msg + " " + request.getRequestURI()); 26 response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); 27 28 return null; 29 } 30 31 path = path.substring(prefix.length()); 32 int slash = path.lastIndexOf("/"); 33 int period = path.lastIndexOf("."); 34 if ((period >= 0) && (period > slash)) { 35 path = path.substring(0, period); 36 } 37 return (path); 38 39 }
從request中獲取請求的url.path = request.getPathInfo();
在對獲取的path進行處理:
1 path = path.substring(prefix.length()); 2 int slash = path.lastIndexOf("/"); 3 int period = path.lastIndexOf("."); 4 if ((period >= 0) && (period > slash)) { 5 path = path.substring(0, period); 6 } 7 return (path);
2.根據獲取的url-path來構建ActionMapping
ActionMapping mapping = processMapping(request, response, path);
1 protected ActionMapping processMapping(HttpServletRequest request, 2 HttpServletResponse response, 3 String path) 4 throws IOException { 5 6 // Is there a mapping for this path? 7 ActionMapping mapping = (ActionMapping) 8 moduleConfig.findActionConfig(path); 9 10 // If a mapping is found, put it in the request and return it 11 if (mapping != null) { 12 request.setAttribute(Globals.MAPPING_KEY, mapping); 13 return (mapping); 14 } 15 16 // Locate the mapping for unknown paths (if any) 17 ActionConfig configs[] = moduleConfig.findActionConfigs(); 18 for (int i = 0; i < configs.length; i++) { 19 if (configs[i].getUnknown()) { 20 mapping = (ActionMapping) configs[i]; 21 request.setAttribute(Globals.MAPPING_KEY, mapping); 22 return (mapping); 23 } 24 } 25 26 // No mapping can be found to process this request 27 String msg = getInternal().getMessage("processInvalid"); 28 log.error(msg + " " + path); 29 response.sendError(HttpServletResponse.SC_NOT_FOUND, msg); 30 31 return null; 32 }
這個過程主要是從struts-config.xml中讀取<action-mapping>結點的action信息,將所有的<action>結點保存到ActionMapping中.
3.獲取ActionForm,
ActionForm form = processActionForm(request, response, mapping);
上一步通過url已經定位到了相應的action,然後通過 String name = mapping.getName(); 獲取actionform(該項在<form-beans>中獲取),同時設置該action的作用域(request/session默認session).再將創建號的actionform放到request/session中.
4.從actionform中獲取相應的值,完成相應數據的賦值,這其中包括類型的轉換,使用了第三方的工具類BeanUtils.
5.創建相應的action
protected Action processActionCreate(HttpServletRequest request,HttpServletResponse response,ActionMapping mapping)
actionform信息存在於actionmapping中。首先根據action類的完整名稱(<action>標籤下面的type),如果已經存在直接返回;否則再使用反射機制創建action。
6.最終執行action的execute方法。
ActionForward forward =processActionPerform(request, response,action, form, mapping);
從中執行action的execute方法,返回actinforward,再根據返回的actionforward來實現轉發/轉向。
具體的處理流程如下圖:
附件一 struts-config.xml
<struts-config> <form-beans> <form-bean name="loginactionform" type="com.volshell.actionform.LoginActionForm"/> </form-beans> <action-mappings> <action path="/login" name="loginactionform" type="com.volshell.action.LoginAction" scope="request"> <forward name="error" path="/login_fail.jsp"></forward> <forward name="success" path="/login_success.jsp"></forward> </action> </action-mappings> </struts-config>