public class ActionServlet { /* * 不管是get请求方式,还是post请求方式.都会执行到这个process(); */ protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { /* 获得ModuleUtils的实例,在selectModule(request,getServletContext()); * ModuleUtils内部引用到了RequestProcessor类的 * static final String INCLUDE_SERVLET_PATH ="javax.servlet.include.servlet_path" * 根据这个string去servletContext(servlet上下文环境)里面去取这个匹配名字 * 以及去取一个ModuleConfig进行相关的操作. */ ModuleUtils.getInstance().selectModule(request, getServletContext()); ModuleConfig config = getModuleConfig(request); // 调用内部私有方法. RequestProcessor processor = getProcessorForModule(config); if (processor == null) { /* 这里调用了 RequestProcessor 作了一系列初始化工作也用到了 * RequestUtil类 , ControlConfig类.把processor这个请求处理类处理好. */ processor = getRequestProcessor(config); } /* 这个方法内部作rquest的包装工作. * 作了大量的工作, 出现错误还要保存到消息机制里 * 把请求的path获取到,还做了些把local保存到本地工作. * 把contextType = "text/html"保存到response.setContextType(str)范围里面. * 在ActionForm 里扩展了一些文件上传功能. */ processor.process(request, response); }// process() end! } // ActionServlet class end! /** package org.apache.struts.action; class RequestProcess */ public void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Wrap multipart requests with a special wrapper request = processMultipart(request); // Identify the path component we will use to select a mapping String path = processPath(request, response); if (path == null) { return; } if (log.isDebugEnabled()) { log.debug("Processing a '" + request.getMethod() + "' for path '" + path + "'"); } // Select a Locale for the current user if requested processLocale(request, response); // Set the content type and no-caching headers if requested processContent(request, response); processNoCache(request, response); // General purpose preprocessing hook if (!processPreprocess(request, response)) { return; } this.processCachedMessages(request, response); // Identify the mapping for this request ActionMapping mapping = processMapping(request, response, path); if (mapping == null) { return; } // Check for any role required to perform this action if (!processRoles(request, response, mapping)) { return; } /* 细心的您会发现, mapping对象 作为参数贯穿了下面的方法*/ // Process any ActionForm bean related to this request ActionForm form = processActionForm(request, response, mapping); // 作了package = "org.apache.struts.taglib.html";等 主装操作. processPopulate(request, response, form, mapping); // Validate any fields of the ActionForm bean, if applicable /* 也就是取寻找 <action-mappings> <action validate="xxx" /> */ 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; } // Process a forward or include specified by this mapping /* 对应 <action-mapping> <action forward> */ if (!processForward(request, response, mapping)) { return; } /* 对应 <action-mappings> <action include/> */ if (!processInclude(request, response, mapping)) { return; } // Create or acquire the Action instance to process this request /* 在actionForm的工作作完后可以来获得action对象 * 而在Action的execute()没做什么工作,直接return null; * 可能是便于 扩展的。 */ Action action = processActionCreate(request, response, mapping); if (action == null) { return; } // Call the Action instance itself // 从action实例里把ActionForward对象取出来。 ActionForward forward = processActionPerform(request, response, action, form, mapping); // Process the returned ActionForward instance // 最后的跳转也就是封装了servlet的方法。 processForwardConfig(request, response, forward); /* * total: 感觉只要跟踪弄懂一个请求操作就可以,其他的process都差不多。 */ }// process() end! /* package org.apache.struts.util; class ModuleUtils;*/ public void selectModule( String prefix, HttpServletRequest request, ServletContext context) { // Expose the resources for this module ModuleConfig config = getModuleConfig(prefix, context); if (config != null) { request.setAttribute(Globals.MODULE_KEY, config); } else { request.removeAttribute(Globals.MODULE_KEY); } // 怎么存的就怎么取吧, 如果 not null 就保存到 request作用域范围里. MessageResourcesConfig[] mrConfig = config.findMessageResourcesConfigs(); for(int i = 0; i < mrConfig.length; i++) { String key = mrConfig[i].getKey(); MessageResources resources = (MessageResources) context.getAttribute(key + prefix); if (resources != null) { request.setAttribute(key, resources); } else { request.removeAttribute(key); } } }// selectModule() end!