1、Struts2架构图 
  这是Struts2官方站点提供的Struts 2 的整体结构。 
  

  执行流程图

  

 2、Struts2部分类介绍 
  这部分从Struts2参考文档中翻译就可以了。 
ActionMapper 
        ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等 java Servlet类的依赖。Struts2中它的默认实现类是DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式,它自己也有Restful的实现,具体可以参考文档的docs\actionmapper.html。 
ActionProxy&ActionInvocation 
        Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默认实现DefaultActionProxy是由ActionInvocation持有Action实例。ActionProxy作用是如何取得Action,无论是本地还是远程。而 ActionInvocation的作用是如何执行Action,拦截器的功能就是在ActionInvocation中实现的。 
ConfigurationProvider&Configuration 
        ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主要是尤其实现类 XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider来解析。

    3、Struts2请求流程 
  1、客户端发送请求 
  2、请求先通过ActionContextCleanUp-->FilterDispatcher 
  3、FilterDispatcher通过ActionMapper来决定这个Request需要调用哪个Action 
  4、如果ActionMapper决定调用某个Action,FilterDispatcher把请求的处理交给ActionProxy,这儿已经转到它的Delegate--Dispatcher来执行 
  5、ActionProxy根据ActionMapping和ConfigurationManager找到需要调用的Action类 
  6、ActionProxy创建一个ActionInvocation的实例 
  7、ActionInvocation调用真正的Action,当然这涉及到相关拦截器的调用 
  8、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现。

  另一个版本:大同小异~ 
  一个请求在Struts2框架中的处理大概分为以下几个步骤: 
.客户端提起一个(HttpServletRequest)请求,如上文在浏览器中输入”http://localhost:8080/TestMvc/add.action”就是提起一个(HttpServletRequest)请求。 
  2.请求被提交到一系列(主要是三层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、 FilterDispatcher)。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到 FilterDispatcher。 
  3.FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter

其代码如下:

Java代码 
  1. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException ...{
  2. HttpServletRequest request = (HttpServletRequest) req;
  3. HttpServletResponse response = (HttpServletResponse) res;
  4. ServletContext servletContext = filterConfig.getServletContext();
  5. // 在这里处理了HttpServletRequest和HttpServletResponse。
  6. DispatcherUtils du = DispatcherUtils.getInstance();
  7. du.prepare(request, response);//正如这个方法名字一样进行locale、encoding以及特殊request parameters设置
  8. try ...{
  9. request = du.wrapRequest(request, servletContext);//对request进行包装
  10. } catch (IOException e) ...{
  11. String message = "Could not wrap servlet request with MultipartRequestWrapper!";
  12. LOG.error(message, e);
  13. throw new ServletException(message, e);
  14. }
  15. ActionMapperIF mapper = ActionMapperFactory.getMapper();//得到action的mapper
  16. ActionMapping mapping = mapper.getMapping(request);// 得到action 的 mapping
  17. if (mapping == null) ...{
  18. // there is no action in this request, should we look for a static resource?
  19. String resourcePath = RequestUtils.getServletPath(request);
  20. if ("".equals(resourcePath) && null != request.getPathInfo()) ...{
  21. resourcePath = request.getPathInfo();
  22. }
  23. if ("true".equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT))
  24. && resourcePath.startsWith("/webwork")) ...{
  25. String name = resourcePath.substring("/webwork".length());
  26. findStaticResource(name, response);
  27. } else ...{
  28. // this is a normal request, let it pass through
  29. chain.doFilter(request, response);
  30. }
  31. // WW did its job here
  32. return;
  33. }
  34. Object o = null;
  35. try ...{
  36. //setupContainer(request);
  37. o = beforeActionInvocation(request, servletContext);
  38. //整个框架最最核心的方法,下面分析
  39. du.serviceAction(request, response, servletContext, mapping);
  40. } finally ...{
  41. afterActionInvocation(request, servletContext, o);
  42. ActionContext.setContext(null);
  43. }
  44. }
  45. du.serviceAction(request, response, servletContext, mapping);
  46. //这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
  47. public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) ...{
  48. HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());  //实例化Map请求 ,询问ActionMapper是否需要调用某个Action来处理这个(request)请求
  49. extraContext.put(SERVLET_DISPATCHER, this);
  50. OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
  51. if (stack != null) ...{
  52. extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack));
  53. }
  54. try ...{
  55. ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);
  56. //这里actionName是通过两道getActionName解析出来的, FilterDispatcher把请求的处理交给ActionProxy,下面是ServletDispatcher的 TODO:
  57. request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
  58. proxy.execute();
  59. //通过代理模式执行ActionProxy
  60. if (stack != null)...{
  61. request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack);
  62. }
  63. } catch (ConfigurationException e) ...{
  64. log.error("Could not find action", e);
  65. sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
  66. } catch (Exception e) ...{
  67. log.error("Could not execute action", e);
  68. sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
  69. }
  70. }

  4.FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。 
  5.ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类. 
如上文的struts.xml配置

Java代码 
  1. <?xml version="1.0" encoding="GBK"?>
  2. <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
  3. <struts>
  4. <include file="struts-default.xml"/>
  5. <package name="struts2" extends="struts-default">
  6. <action name="add"
  7. class="edisundong.AddAction" >
  8. <result>add.jsp</result>
  9. </action>
  10. </package>
  11. </struts>

  如果提交请求的是add.action,那么找到的Action类就是edisundong.AddAction。 
  6.ActionProxy 创建一个ActionInvocation的实例,同时ActionInvocation通过代理模式调用Action。但在调用之前 ActionInvocation会根据配置加载Action相关的所有Interceptor。(Interceptor是struts2另一个核心级的概念)

下面我们来看看ActionInvocation是如何工作的:

ActionInvocation 是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。ActionInvocation 是一个接口,而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。

Interceptor 的调度流程大致如下: 
1. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。 
2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。

Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、 WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在 Action执行前后运行。 
那么什么是拦截器。 
拦截器就是AOP(Aspect-Oriented Programming)的一种实现。(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。) 
拦截器的例子这里就不展开了。 
struts-default.xml文件摘取的内容:

Java代码 
  1. < interceptor name ="alias" class ="com.opensymphony.xwork2.interceptor.AliasInterceptor" />
  2. < interceptor name ="autowiring" class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" />
  3. < interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" />
  4. < interceptor name ="conversionError" class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" />
  5. < interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" />
  6. < interceptor name ="debugging" class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
  7. < interceptor name ="external-ref" class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" />
  8. < interceptor name ="execAndWait" class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" />
  9. < interceptor name ="exception" class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" />
  10. < interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" />
  11. < interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" />
  12. < interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" />
  13. < interceptor name ="model-driven" class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" />
  14. < interceptor name ="scoped-model-driven" class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" />
  15. < interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
  16. < interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" />
  17. < interceptor name ="static-params" class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" />
  18. < interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" />
  19. < interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" />
  20. < interceptor name ="sessionAutowiring" class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" />
  21. < interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" />
  22. < interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" />
  23. < interceptor name ="token-session" class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
  24. < interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" />
  25. < interceptor name ="workflow" class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" />
  26. < interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" />
  27. < interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" />
  28. < interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />

  7.一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。如上文中将结构返回“add.jsp”,但大部分时候都是返回另外一个action,那么流程又得走一遍

Struts框架核心工作流程与原理的更多相关文章

  1. Struts框架的执行流程或原理

    Struts2的执行流程如下: 1.浏览器发送请求,经过一系列的过滤器,到达StrutsPreapareAndExecteFilter 2.StrutsPrepareAndExectueFilter通 ...

  2. Appium 框架工作流程及原理

    目前Appium框架可以时支持android 和 ios 两个操作系统的App自动化测试,咱们分别对以下两款操作系统的工作流程进行说明. 一.appium-Android工作流 在Android端,a ...

  3. SSM工作流程与原理详解

    自学ssm->springboot->springcloud,所以很多东西会用但理解较浅,所以现在从最开始的ssm开始进行对原理以及运行过程的整理知识归纳,若有错误感谢指正. Spring ...

  4. Mybatis工作流程及其原理与解析

    Mybatis简介:    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBat ...

  5. Scrapy中的核心工作流程以及POST请求

    五大核心组件工作流程 post请求发送 递归爬取 五大核心组件工作流程 引擎(Scrapy)用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler)用来接受引擎发过来的请求, ...

  6. Yarn框架和工作流程研究

    一.概述     将公司集群升级到Yarn已经有一段时间,自己也对Yarn也研究了一段时间,现在开始记录一下自己在研究Yarn过程中的一些笔记.这篇blog主要主要从大体上说说Yarn的基本架构以及其 ...

  7. DNS工作流程及原理 域名、IP与DNS的关系

    转自:http://blog.csdn.net/maminyao/article/details/7390208 一.DNS服务概述 DNS是Domain Name System的缩写,即域名系统.其 ...

  8. Struts 2 Spring Hibernate三大框架的执行流程以及原理

    Struts2框架 一.简介 Struts2是一个相当强大的Java Web开源框架,是一个基于POJO的Action的MVC Web框架.它基于当年的WebWork和XWork框架,继承其优点,同时 ...

  9. SSM三大框架的运行流程、原理、核心技术详解

    一.Spring部分1.Spring的运行流程第一步:加载配置文件ApplicationContext ac = new ClassPathXmlApplicationContext("be ...

随机推荐

  1. Event.target和Event.currentTarget的区别

    <style> * { margin:0; padding:0; list-style:none; } #ul { width:400px; height:250px; margin:0 ...

  2. oracle 11g中文乱码解决的办法一

    oracle中文乱码解决的办法 正常安装完oracle客户端后,插入数据时,发现中文都是问号. PLL/SQL中输入select userenv('LANGUAGE') From Dual,结果为AM ...

  3. Linux服务器密钥安全登录

    使用密钥登录的好处:1.省事,不用每次去敲用户名和密码:2.安全,密钥长度一般是1024位,比我们设的密码要长得多: 以下是为新用户jackson添加密钥登录的步骤. 1.添加用户,并添加到sudoe ...

  4. redis的repl-ping-slave-period和repl-ping-replica-period

    网上很多Redis方面的文章,会涉及到repl-ping-slave-period和repl-ping-replica-period这两个重要参数,从一些中文解释来看,意思差不多,即:SLAVE周期性 ...

  5. 100度享乐电商网 html

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  6. whereis+whatis+man

    使用Linux过程中无论是使用shell命令.程序开发或者用户文档都需要使用到强大的男人man命令. 使用方法也十分简单,以查看ls命令的使用方法为例: man ls man的搜索路径通常包括以下两个 ...

  7. ASP.NET Web API 框架研究 ASP.NET Web API 路由

    ASP.NET Web API 核心框架是一个独立的.抽象的消息处理管道,ASP.NET Web API有自己独立的路由系统,是消息处理管道的组成部分,其与ASP.NET路由系统有类似的设计,都能找到 ...

  8. 16位CRC校验_Delphi

    unit Modbus_main; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, G ...

  9. A - Playground

    My kid's school cleared a large field on their property recently to convert it into a playing area.  ...

  10. OS基础:动态链接库(二)

    1.vc6.0新建工程MFC AppWizard[dll]工程 命名LptMfcDll1 2.在lptMfcDll1.h添加函数名声明 添加的代码: //lptAddBegin void lptMfc ...