`
xiaoheliushuiya
  • 浏览: 402214 次
文章分类
社区版块
存档分类
最新评论

Struts2框架核心工作流程与原理

 
阅读更多

 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框架中的处理大概分为以下几个步骤:
  1.客户端提起一个(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. publicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain)throwsIOException,ServletException...{
  2. HttpServletRequestrequest=(HttpServletRequest)req;
  3. HttpServletResponseresponse=(HttpServletResponse)res;
  4. ServletContextservletContext=filterConfig.getServletContext();
  5. //在这里处理了HttpServletRequest和HttpServletResponse。
  6. DispatcherUtilsdu=DispatcherUtils.getInstance();
  7. du.prepare(request,response);//正如这个方法名字一样进行locale、encoding以及特殊requestparameters设置
  8. try...{
  9. request=du.wrapRequest(request,servletContext);//对request进行包装
  10. }catch(IOExceptione)...{
  11. Stringmessage="CouldnotwrapservletrequestwithMultipartRequestWrapper!";
  12. LOG.error(message,e);
  13. thrownewServletException(message,e);
  14. }
  15. ActionMapperIFmapper=ActionMapperFactory.getMapper();//得到action的mapper
  16. ActionMappingmapping=mapper.getMapping(request);//得到action的mapping
  17. if(mapping==null)...{
  18. //thereisnoactioninthisrequest,shouldwelookforastaticresource?
  19. StringresourcePath=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. Stringname=resourcePath.substring("/webwork".length());
  26. findStaticResource(name,response);
  27. }else...{
  28. //thisisanormalrequest,letitpassthrough
  29. chain.doFilter(request,response);
  30. }
  31. //WWdiditsjobhere
  32. return;
  33. }
  34. Objecto=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. publicvoidserviceAction(HttpServletRequestrequest,HttpServletResponseresponse,Stringnamespace,StringactionName,MaprequestMap,MapparameterMap,MapsessionMap,MapapplicationMap)...{
  48. HashMapextraContext=createContextMap(requestMap,parameterMap,sessionMap,applicationMap,request,response,getServletConfig());//实例化Map请求,询问ActionMapper是否需要调用某个Action来处理这个(request)请求
  49. extraContext.put(SERVLET_DISPATCHER,this);
  50. OgnlValueStackstack=(OgnlValueStack)request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
  51. if(stack!=null)...{
  52. extraContext.put(ActionContext.VALUE_STACK,newOgnlValueStack(stack));
  53. }
  54. try...{
  55. ActionProxyproxy=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(ConfigurationExceptione)...{
  64. log.error("Couldnotfindaction",e);
  65. sendError(request,response,HttpServletResponse.SC_NOT_FOUND,e);
  66. }catch(Exceptione)...{
  67. log.error("Couldnotexecuteaction",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. <?xmlversion="1.0"encoding="GBK"?>
  2. <!DOCTYPEstrutsPUBLIC"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN""http://struts.apache.org/dtds/struts-2.0.dtd">
  3. <struts>
  4. <includefile="struts-default.xml"/>
  5. <packagename="struts2"extends="struts-default">
  6. <actionname="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. <interceptorname="alias"class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
  2. <interceptorname="autowiring"class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
  3. <interceptorname="chain"class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
  4. <interceptorname="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
  5. <interceptorname="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor"/>
  6. <interceptorname="debugging"class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
  7. <interceptorname="external-ref"class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
  8. <interceptorname="execAndWait"class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
  9. <interceptorname="exception"class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
  10. <interceptorname="fileUpload"class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
  11. <interceptorname="i18n"class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
  12. <interceptorname="logger"class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
  13. <interceptorname="model-driven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
  14. <interceptorname="scoped-model-driven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
  15. <interceptorname="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
  16. <interceptorname="prepare"class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
  17. <interceptorname="static-params"class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
  18. <interceptorname="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/>
  19. <interceptorname="servlet-config"class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
  20. <interceptorname="sessionAutowiring"class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
  21. <interceptorname="timer"class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
  22. <interceptorname="token"class="org.apache.struts2.interceptor.TokenInterceptor"/>
  23. <interceptorname="token-session"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
  24. <interceptorname="validation"class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>
  25. <interceptorname="workflow"class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
  26. <interceptorname="store"class="org.apache.struts2.interceptor.MessageStoreInterceptor"/>
  27. <interceptorname="checkbox"class="org.apache.struts2.interceptor.CheckboxInterceptor"/>
  28. <interceptorname="profiling"class="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>

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

分享到:
评论

相关推荐

    Struts2基本原理

    Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务... Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,所以说Struts 2是WebWork的升级版本。

    struts2流程与流程图

    一个请求在Struts 2框架中的处理大概分为以下几个步骤。  客户端提交一个(HttpServletRequest)请求,如上文在浏览器中输入 http://localhost: 8080/bookcode/ch2/Reg.action就是提交一个(HttpServletRequest)...

    SSH框架详解

    个人中的SSH详细介绍,包括struts1的工作原理、Struts1优缺点(为什么要用strust1)、struts1的工作原理及基本配置详解、struts2工作原理、struts2运行机制、Struts2的工作流程、Struts2工作原理、Struts1与Struts2...

    Struts2 in action中文版

    1.3.3 Struts 2的工作原理 12 1.4 小结 14 第2章 初识Struts 2 16 2.1 声明性架构 16 2.1.1 两种配置 16 2.1.2 声明架构的两种方式 17 2.1.3 智能默认值 20 2.2 简单的HelloWorld示例 20 2.2.1 部署示例应用程序 20...

    精通Struts基于MVC的Java Web设计与开发 孙卫琴 光盘

    第4章到第7章深入探讨了Struts框架的核心组件ActionServlet和RequestProcessor的实现原理,详细介绍了开发Struts应用的模型、视图和控制器的各种技术,细致的描述了Struts配置文件的每个元素的使用方法。第8章到第9...

    精通 Struts:基于 MVC 的 JavaWeb 设计与开发(PDF)

    第4章到第7章深入探讨了Struts框架的核心组件ActionServlet和RequestProcessor的实现原理,详细介绍了开发Struts应用的模型、视图和控制器的各种技术,细致的描述了Struts配置文件的每个元素的使用方法。第8章到第9...

    Struts框架的应用研究.pdf

    提高网络环境中服务器上应用软件的质量和研发速度是软件产业界备受关注...同时 ,对采用 Struts进行应用系统开发的方法及流程进行了阐述 ,并以作者参与的电力营销系统的设计为例说明了 Struts框架在程序开发中的具体应用

    精通struts:基于mvc的java web设计与开发part2

    第4章到第7章深入探讨了Struts框架的核心组件ActionServlet和 RequestProcessor的实现原理,详细介绍了开发Struts应用的模型、视图和控制器的各种技术,细致的描述了Struts配置文件的每个元素的使用方法。...

    精通Struts_基于MVC的Java Web设计与开发

    第4章到第7章深入探讨了Struts框架的核心组件ActionServlet和RequestProcessor的实现原理,详细介绍了开发Struts应用的模型、视图和控制器的各种技术,细致的描述了Struts配置文件的每个元素的使用方法。第8章到第9...

    精通struts:基于mvc的java web设计与开发part3

    第4章到第7章深入探讨了Struts框架的核心组件ActionServlet和 RequestProcessor的实现原理,详细介绍了开发Struts应用的模型、视图和控制器的各种技术,细致的描述了Struts配置文件的每个元素的使用方法。...

    精通struts:基于mvc的java web设计与开发part1

    第4章到第7章深入探讨了Struts框架的核心组件ActionServlet和 RequestProcessor的实现原理,详细介绍了开发Struts应用的模型、视图和控制器的各种技术,细致的描述了Struts配置文件的每个元素的使用方法。...

    信息办公基于struts的图书管理系统-struts-ts.rar

    通过学习这个系统,你可以深入了解Struts框架的工作原理和使用方法,提高自己的Java Web开发能力。同时,这个项目也可以帮助初学者快速掌握图书管理系统的开发流程和技术要点,为今后的工作和学习打下坚实的基础。...

    Struts原理、开发及项目实施

    Struts原理、开发及项目实施 Holen 2002-9-12 &lt;br/&gt;1、 摘要 2、 关键词 3、 Framework 4、 Struts的起源 5、 Struts工作原理 6、 Struts安装 7、 一个实例 8、 Struts优缺点...

    Java Web 整合开发和项目实践(SSH) 高清.part1

    第2篇为表现层框架Struts技术,介绍了Struts2的工作原理、核心文件、数据校验与国际化、标签库、拦截器等。第3篇为持久层框架Hibernate技术,介绍了Hibernate的工作原理、核心文件、核心接口及相关插件的使用方法。...

    SSH的jar包.rar

    下面粗略的分析下FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter。 Hibernate 的原理 1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件 2.由hibernate....

    Java Web程序设计教程

    5.2.1struts2的工作流程 84 5.2.2struts2的简单应用 85 5.3struts2基础 87 5.3.1action详解 88 5.3.2结果与视图 91 5.3.3struts.xml的配置 94 5.4值栈与ognl表达式 100 5.5struts2的标签库 103 5.5.1控制...

    Sturts的工作原理

    Structs 框架的核心是一个弹性的控制层,基于如 Java Servlets,JavaBeans,ResourceBundles与XML等标准技术,以及 Jakarta Commons 的一些类库。Struts有一组相互协作的类(组件)、Serlvet以及jsp tag lib组成。...

    Java Web 整合开发和项目实践(SSH)

    第2篇为表现层框架Struts技术,介绍了Struts2的工作原理、核心文件、数据校验与国际化、标签库、拦截器等。第3篇为持久层框架Hibernate技术,介绍了Hibernate的工作原理、核心文件、核心接口及相关插件的使用方法。...

    J2EE开源编程精要15讲--整合 源代码

    开源开发工具eclipse、用eclipse开发java web应用程序、struts应用技巧、struts的核心组件、struts的高级功能、 hibernate基本原理、hibernate的核心组件、hibernate的高级功能、 struts与hibernate的整合应用、...

    Java Web 整合开发和项目实践(SSH).part3

    第2篇为表现层框架Struts技术,介绍了Struts2的工作原理、核心文件、数据校验与国际化、标签库、拦截器等。第3篇为持久层框架Hibernate技术,介绍了Hibernate的工作原理、核心文件、核心接口及相关插件的使用方法。...

Global site tag (gtag.js) - Google Analytics