Struts2总结之Action和Result

    当一个请求到达Servlet容器(Tomcate)后,将被传递给一个标准的过滤器链,在这个过滤器链中包括了可选的ActionContextCleanUp过滤器.当在Struts2 Web应用程序中集成SiteMesh时,才会用到此链。接下来,必须的FilterDispatcher被调用,它轮询ActonMapper(org.apache.struts2.dispatcher.mapper.ActionMapper),以便确认这个请求是否应该调用一个action。如果ActionMapper确定了一个请求应该被调用,那么FilterDispatcher就把控制权委派给ActionProxy(com.opensymphony.xwork2.ActionProxy),ActionProxy询问框架的配置文件管理器(它从struts.xml文件中读取配置信息),接下来,ActionProxy创建一个实现了命令模式的ActionInvocation,ActionInvocation在调用action之前会一次调用所有配置的连接器。一旦action执行返回,ActionInvocation就要struts.xml里面配置),然后执行这个result,通常情况下result会调用JSP或者freeMarker模板呈现页面(但不总是这样,result也可以是一个action链). 

这里介绍一下Struts2框架的组成部分: 
1.ActionMapper和ActionMapping: 
    org.apache.struts2.dispatcher.mapper.ActionMapper接口在HTTP请求和action调用请求之间提供了一个映射,当给定一个HTTP请求时,ActionMapper根据请求的URL来查找是否有对应的action调用。如果有则返回一个描述了action调用的 
ActionMapping,如果没有找到匹配的action调用请求,则返回null; 
    Struts2框架对该接口提供的默认实现是org.apacher.struts2.disspatcher.mapper. 
DefaultActionMapper. 
    ActionMapping本质上是一个数据传输对象,它将Action类和要执行的方法的详细资料收集在一起,ActionMapping由org.apache.struts2.dispatcher.Dispatcher和各种用户接口组合使用。 
    ActionMapping的完整类名是 
       org.apacher.struts2.dispatcher.mapper.ActionMapping. 
2.ActionProxy&ActionInvocation 
        Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默认实现DefaultActionProxy是由ActionInvocation持有Action实例。ActionProxy作用是如何取得Action,无论是本地还是远程。而ActionInvocation的作用是如何执行Action,拦截器的功能就是在ActionInvocation中实现的。 
ConfigurationProvider&Configuration 
        ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主要是尤其实现类XmlConfigurationProvider及其子类 
StrutsXmlConfigurationProvider来解析。 
3.ActionContext 
        是action执行的上下文,每一个上下文都相当于一个action执行所需要的一组对象的容器,例如session,application,parameters,locale等. 
ActionContext包含了大量执行期间有用的环境信息,这些信息由org.apacher. 
struts2.dispatcher.Dispatcher类在创建ActionProxy前设置, 
   并封装到一个Map对象extraContext中, 
   Map<String, Object> extraContext = createContextMap(request, 
               response, mapping, context); 
   该对象随后被作为参数传递给ActionProxyFactory的createActionProxy()方法. 
   ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( 
                 namespace, name, method, extraContext, true, false); 
   ActionContext是线程本地的,这就意味着在ActionContext中存储的值对于每个线程都是唯一的,所以对于某个Action,如果要从ActionContext中获取数据,不需要担心线程安全问题。 
   ActionContext是被存放在当前线程中的,获取ActionContext也是从ThreadLocal中获取的。所以在执行拦截器、 action和result的过程中,由于他们都是在一个线程中按照顺序执行的,所以可以可以在任意时候在ThreadLocal中获取 ActionContext。ActionContext包括了很多信息,比如Session、Application、Request、Locale、ValueStack等,其中 ValueStack可以解析ognl表达式,来动态后去一些值,同时可以给表达式提供对象。 
   ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器 (其实我们这里的容器就是一个Map而已),它存放的是Action在执行时需要用到的对象. 一般情况, 我们的ActionContext都是通过: ActionContext context = (ActionContext) actionContext.get(); 来获取的.我们再来看看这里的actionContext对象的创建: 
    static ThreadLocal actionContext = new ActionContextThreadLocal(); 
    ActionContextThreadLocal是实现ThreadLocal的一个内部类.ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突.这样,我们 ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.通过ActionContext取得 
   HttpSession: Map session = ActionContext.getContext().getSession(); 
   (通过Map模拟HttpServlet的对象,操作更方便) 
   ActionConext的完整类名是:org.opensymphony.xwork2.ActionContext. 
4.result 
   com.opensymphony.xwork2.Result接口代表action执行后的结果。每一个action 
执行都需要返回一个String类型的结果码,用于配置result元素列表中选择对应的result。result在struts.xml文件中进行配置。 
   Result接口的不同实现代表了不同类型的结果输出,Struts2框架提供的Result 
实现包括了Servlet转发,Servlet重定向,Velocity模板输出,FreeMarker模板输出, 
JasperReports(可生成PDF,CVS,XML等)和ActionChainResult(可用于从当前action 
到其他action的链式处理)等. 

Struts2框架的调用流程: 
1>当Servlet容器接收到一个请求之后,将请求交给了在web.xml文件中配置的过滤器  FilterDispatcher,调用它的doFilter()方法。 
2>FilterDispatcher询问ActionMapper,以便确认这个请求是否有对应的action调用. 
3>ActionMapper返回一个描述了action调用的ActionMapping对象 
4>FilterDispatcher调用Dispatcher类的serviceAction()方法。 
5>FilterDispatcher调用ActionProxy的execute()方法。 
6>ActionProxy设置ActionInvocation对象的执行上下文,然后调用其invoke()方法。 
7>ActionInvocation的invoke()方法从拦截器映射中查找尚未执行的拦截器,调用它的intercepet(invocation)方法,并将自身对象的引用作为参数传递个拦截器。 
8>拦截器完成某些预处理工作后,反过来调用ActionInvocation的invoke()方法, 
ActionInvocation维护着自己的状态,所以它知道哪些拦截器已经被执行,如果还没有执行的拦截器,就继续执行它的intercept(invocation)方法。 
9>如果所有的拦截器都已经执行过了,就调用action实例的execute()方法(如果在struts.xml文件中没有被设置成其它方法的话). 
10>ActionInvocation根据action执行返回的结果码,查找对应的Result,调用result的execute(invocation),将结果页面呈现给用户. 
11>ActionInvocation的invoke()方法将控制权返回给拦截器映射中的最后一个拦截器,该拦截器完成所有必须的后期处理工作,然后从intercepter(invocation)返回,允许前一个拦截器执行它自己的后处理工作。如此反复,直到所有的拦截器都成功返回。 
12> ActionInvocation的invoke0方法执行完毕后,向ActionProxy返回一个String类型的结果码,最后ActionProxy清理状态并返回. 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值