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>