你的位置:首页 > Java教程

[Java教程]Struts2运行流程


   这篇文章大部分是转载的,虽然不知道作者是谁,但是还是非常膜拜的,描述的非常清晰,我觉得要是自己去陈诉也没有这么好,中间我修改了最新的核心控制器名称,主要是struts2的核心控制器现在并不是FilterDispatcher对象,而是StrutsPrepareAndExcuteFilter对象;中间有许多图片还是FilterDisptcher,我这边偷下懒,大家知道就行

第一步 :我们先来看下struts2官方提供的运行流程图

 

这张图上分了好多块,彼此之间相互联系,先浏览一下各块的名字,再留心一下运行图最下面的图例,分为四种颜色。

  • 橙色是Servlet Filters,过滤器链,所有的请求都要经过Filter链的处理。
  • 浅蓝色是Struts Core,Struts2的核心部分,Struts2中已经做好的功能,在实际开发中不需要动它们。
  • 浅绿色是Interceptors,Struts2的拦截器。Struts2提供了很多默认的拦截器,可以完成日常开发的绝大部分工作;当然,也可以自定义拦截器,用来实现具体业务需要的功能。
  • 浅黄色是User Created,由开发人员创建的,包括struts.

 

第二部分我们粗略的陈诉下各个模块作用

                  

  • StrutsPrepareAndExcuteFilter是整个Struts2的调度中心,根据ActionMapper的结果来决定是否处理请求,如果ActionMapper指出该URL应该被Struts2处理,那么它将会执行Action处理,并停止过滤器链上还没有执行的过滤器。
  • ActionMapper提供了HTTP请求与action执行之间的映射,简单点说,ActionMapper会判断这个请求是否应该被 Struts2处理,如果需要Struts2处理,ActionMapper会返回一个对象来描述请求对应的ActionInvocation的信息。
  • ActionProxy是一个特别的中间层,位于Action和xwork之间,使得我们在将来有机会引入更多的实现方式,比如通过WebService来实现等。
  • ConfigurationManager是xwork配置的管理中心,通俗的讲,可以把它看做struts.
  • struts.
  • ActionInvocation:真正调用并执行Action,它拥有一个Action实例和这个Action所依赖的拦截器实例。ActionInvocation会执行这些拦截器、Action以及相应的Result。
  • Interceptor(拦截器):拦截器是一些无状态的类,拦截器可以自动拦截Action,它们给开发者提供了在Action运行之前或Result运行之后来执行一些功能代码的机会。类似于我们熟悉的javax.servlet.Filter。
  • Action:动作类是Struts2中的动作执行单元。用来处理用户请求,并封装业务所需要的数据。
  • Result:Result就是不同视图类型的抽象封装模型,不同的视图类型会对应不同的Result实现,Struts2中支持多种视图类型,比如Jsp,FreeMarker等。
  • Templates:各种视图类型的页面模板,比如JSP就是一种模板页面技术。
  • Tag Subsystem:Struts2的标签库,它抽象了三种不同的视图技术JSP、velocity、freemarker,可以在不同的视图技术中,几乎没有差别的使用这些标签。

 

第三部分接下来我们来真正陈诉下运行流程

             前提:我们正在模拟用户登入,进入index.jsp页面,该页面有两个输入框,分别是账号与密码,还有提交按钮,当输入的信息后然后提交到后台处理,插入web.

 

Java代码  收藏代码

  1. <!-- 配置Struts2控制器 -->  
  2. <filter>  
  3.     <filter-name>struts2</filter-name>  
  4.     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  5. </filter>  
  6.   
  7. <filter-mapping>  
  8.     <filter-name>struts2</filter-name>  
  9.     <url-pattern>*.action</url-pattern>  
  10. </filter-mapping>  

 

 

             过程:

 

1首先是在登录页面,用户填入帐号和密码,然后点击提交按钮,好了,就从这里开始分析背后的处理流程,这是我们进行分析的起点。

2当用户提交登录请求后,请求的URL为:“/helloworld /helloworldAction.action”,请求会被Tomcat服务器接收到,Tomcat服务器会根据请求URL中的web上下文,也就是 “/helloworld”,来选择处理这个请求的Web应用,那就是由helloworld这个web工程来处理这个请求。

3Web容器会去读取helloworld这个工程的web.

4Web容器会获取FilterDispatcher这个类的实例,然后回调doFilter方法,进行真正的处理。StrutsPrepareAndExcuteFilter作为前端控制器,是整个Struts2的调度中心。

注意:在架构图上,可以看到有三个过滤器层次,分别是ActionContextCleanUp、 SiteMesh等其他过滤器和FilterDispatcher。这三个层次中,ActionContextCleanUp和 FilterDispatcher是Struts2的过滤器,而SiteMeshSiteMesh等其他过滤器不是。

StrutsPrepareAndExcuteFilter是任何一个Struts2应用都需要配置的,一般出现在过滤器链的最后;如果在StrutsPrepareAndExcuteFilter前出现了如SiteMesh这种特殊的过滤器,还必须在SiteMesh前引用Struts2的ActionContextCleanUp过滤器。

在前面的helloworld中,并没有出现SiteMesh这种特殊的过滤器,所以只需要引用StrutsPrepareAndExcuteFilter就可以了。

这就相当于前进到Struts2架构图上的第一步,如下所示:



 

 

5StrutsPrepareAndExcuteFilter将请求转发给ActionMapper。ActionMapper负责识别当前的请求是否需要Struts2做出处理。这就相当于前进到Struts2架构图上的第二步,如下所示:



 

6ActionMapper告诉StrutsPrepareAndExcuteFilter,需要处理这个请求,StrutsPrepareAndExcuteFilter会停止过滤器链以后的部分,所以通常情况下:StrutsPrepareAndExcuteFilter应该出现在过滤器链的最后。然后建立一个ActionProxy对象,这个对象作为Action与xwork之间的中间层,会代理Action的运行过程。

这就相当于前进到Struts2架构图上的第三步,如下所示:

                   

 

7ActionProxy对象刚被创建出来的时候,并不知道要运行哪个Action,它手里只有从StrutsPrepareAndExcuteFilter中拿到的请求的URL。这时候,它去向ConfigurationManager询问到底要运行哪个Action。

回忆一下,某个特定的URL由哪个Action响应由谁负责,定义在什么地方呢?没错,在struts.

在服务器启动的时候,ConfigurationManager会一次性的把struts.

这就相当于前进到Struts2架构图上的第四步和第五步了,如下所示:



 

 

8:ActionProxy拿到了运行哪个Action、相关的拦截器以及所有可能使用的result信息,就可以着手建立ActionInvocation对象了,ActionInvocation对象描述了Action运行的整个过程。

注意:Action运行绝不仅仅只是运行Action的execute方法这么简单,还包括其他部分,完整的调用过程由ActionInvocation对象负责。

这就相当于前进到Struts2架构图上的第六步,如下所示:



 

9回忆一下,HelloWorld中Action的execute方法运行的时候,是不是它的属性就已经有了请求中的参数呢?这说明,在execute方法之前,有人偷偷的帮我们做了这件事,把请求中的参数赋值到了Action的属性上,这个“有人”就是刚刚说的拦截器。

拦截器的运行被分成两部分,一部分在Action之前运行,一部分在Result之后运行,而且顺序是刚好反过来的。也就是在Action执行前的顺序,比如是拦截器1、拦截器2、拦截器3,那么运行Result之后,再次运行拦截器的时候,顺序就变成拦截器3、拦截器2、拦截器1了。

总之ActionInvocation对象执行的时候比较复杂,会做很多事:

  • 首先按照拦截器的引用顺序依次执行各个拦截器的前置部分。

这就相当于前进到Struts2架构图上的第七步,如下所示:



 

  • 然后执行Action的execute方法

这就相当于前进到Struts2架构图上的第八步,如下所示:



 然后根据execute方法返回的结果,也就是Result,在struts.



 

  • 找到页面后,由于现在的页面一般都是模板页面,在页面上,可以通过Struts2自带的标签库来访问需要的数据,并生成最终页面

这就相当于前进到Struts2架构图上的第十步,如下所示:



 

  • 最后,ActionInvocation对象再按照拦截器的引用顺序的倒序依次执行各个拦截器的后置部分。

这就相当于前进到Struts2架构图上的第十一步,如下所示:



 

10ActionInvocation对象执行完毕后,实际上就已经得到响应对象了,也就是HttpServletResponse对象,最后按与过滤器器配置定义相反的顺序依次经过过滤器,向用户展示出响应的结果。

这就相当于前进到Struts2架构图上的第十二步,得到最终完整的系统架构图了