Struts1的處理流程

 

本文從收到一個請求開始講述,忽略之前的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     }
View Code

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