延长action中属性的生命周期,包括自定义属性,以便在jsp页面中进行访问,让actionContextcleanup过滤器来清除属性,不让action自己清除。

为了使用WebWork,我们只需要在web.xml配置FilterDispatcher一个过滤器即可,阅读一下FilterDispatcher的JavaDoc和源码,我们可以看到它调用了:

finally
 {
            ActionContextCleanUp.cleanUp(req);
 }

在ActionContextCleanUp中,有这样的代码:

req.setAttribute(CLEANUP_PRESENT, Boolean.TRUE);

如果FilterDispatcher检测到这个属性,就不会清除ActionContext中的内容了,而由ActionContextCleanUp后续的代码来清除,保证了一系列的Filter访问正确的ActionContext.

文档中提到,如果用到SiteMesh的Filter或者其他类似Filter,那么设置顺序是:

ActionContextCleanUp filter
 SiteMesh filter
 FilterDispatcher
 所以最后我们的web.xml应该类似这样:

<filter>
        <filter-name>ActionContextCleanUp</filter-name>
        <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>
    </filter>

<filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.webwork.sitemesh.FreeMarkerPageFilter</filter-class>
    </filter>

<filter>
        <filter-name>webwork</filter-name>
        <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
    </filter>

<filter-mapping>
        <filter-name>ActionContextCleanUp</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

<filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

<filter-mapping>
        <filter-name>webwork</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

---------------------------------------------------------------------------------------------------------------------

在Struts 2.1.6之前,ActionContextCleanUp的完整路径是com.opensymphony.webwork.dispatcher.ActionContextCleanUp,现在的路径变成了org.apache.struts2.dispatcher.ActionContextCleanup。

那么这个类究竟有什么用处呢?是不是一定要用呢?

下面是这个类内部的注释。

Special filter designed to work with the FilterDispatcher and allow
for easier integration with SiteMesh. Normally, ordering your filters to have
SiteMesh go first, and then FilterDispatcher go second is perfectly fine.
However, sometimes you may wish to access Struts features, including the
value stack, from within your SiteMesh decorators. Because FilterDispatcher
cleans up the ActionContext, your decorator won't have access to the
data you want.
     By adding this filter, the FilterDispatcher will know to not clean up and
instead defer cleanup to this filter. The ordering of the filters should then be:
1.this filter

2.SiteMesh filter

3.FilterDispatcher

就是说,一般情况下,如果你要用SiteMesh或者其他过滤器,一般是放在FilterDispatcher或者是现在的StrutsPrepareAndExecuteFilter之前。在调用完所有过滤器的doFilter方法后,核心过滤器FilterDispatcher或者StrutsPrepareAndExecuteFilter会清空ActionContext,如果其他过滤器要一直使用value stack等struts的特性时,如果不用ActionContextCleanUp的话,便得不到想要的值。

ActionContextCleanUp 的作用就是上面用粗体标注出来的那一句。它会在doFilter方法里设置一个计数器counter的初始值为1,有了这个值,后续的核心过滤器就不会清 空ActionContext,而是由之前的过滤器也就是ActionContextCleanUp来清空ActionContext。

------------------------------------------------------------------------------------------------------------------------------------------------------

 

1. 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的对象,操作更方便)

2. ServletActionContext

ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了我们上面介绍的ActionContext,它提供了直接与Servlet相关对象访问的 功能,它可以取得的对象有:

(1)javax.servlet.http.HttpServletRequest : HTTPservlet请求对象 
(2)javax.servlet.http.HttpServletResponse : HTTPservlet相应对象 
(3)javax.servlet.ServletContext : Servlet上下文信息 
(4)javax.servlet.ServletConfig : Servlet配置对象 
(5)javax.servlet.jsp.PageContext : Http页面上下文

如何从ServletActionContext里取得Servlet的相关对象:

<1>取得HttpServletRequest对象: HttpServletRequest request = ServletActionContext. getRequest();

<2>取得HttpSession对象: HttpSession session = ServletActionContext. getRequest().getSession();

3. ServletActionContext和ActionContext联系

ServletActionContext和ActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的原则 是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接 去访问Servlet的相关对象.

注意:在使用ActionContext时有一点要注意: 不要在Action的构造函数里使用ActionContext.getContext(), 因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null;同 样,HttpServletRequest req = ServletActionContext.getRequest()也不要放在构造函数中,也不要直接将req作为类变量给其赋值。 至于原因,我想是因为前面讲到的static ThreadLocal actionContext = new ActionContextThreadLocal(),从这里我们可以看出ActionContext是线程安全的,而 ServletActionContext继承自ActionContext,所以ServletActionContext也线程安全,线程安全要求每 个线程都独立进行,所以req的创建也要求独立进行,所以ServletActionContext.getRequest()这句话不要放在构造函数 中,也不要直接放在类中,而应该放在每个具体的方法体中(eg:login()、queryAll()、insert()等),这样才能保证每次产生对象 时独立的建立了一个req。

4.ActionContextClearUp

ActionContextClearUp其实是Defer ClearUP.作用就是延长action中属性的生命周期,包括自定义属性,以便在jsp页面中进行访问,让actionContextcleanup 过滤器来清除属性,不让action自己清除。具体看下面的代码,代码很简单:

Java代码 
  1. public void doFilter(...){
  2. ...
  3. try{
  4. ...
  5. //继续执行所配置的chain中的Filter
  6. chain.doFilter(request, response);
  7. }finally{
  8. //保证在所有动作执行完之后,调用cleanUp
  9. ...
  10. cleanUp(request);
  11. }
  12. }
  13. protected static void cleanUp(ServletRequest req) {
  14. ...
  15. ActionContext.setContext(null);//清除ActionContext实例
  16. Dispatcher.setInstance(null);//清除Dispatcher实例(Dispatcher主要是完成将url解析成对应的Action)
  17. }
Java代码  
  1. public void doFilter(...){
  2. ...
  3. try{
  4. ...
  5. //继续执行所配置的chain中的Filter
  6. chain.doFilter(request, response);
  7. }finally{
  8. //保证在所有动作执行完之后,调用cleanUp
  9. ...
  10. cleanUp(request);
  11. }
  12. }
  13. protected static void cleanUp(ServletRequest req) {
  14. ...
  15. ActionContext.setContext(null);//清除ActionContext实例
  16. Dispatcher.setInstance(null);//清除Dispatcher实例(Dispatcher主要是完成将url解析成对应的Action)
  17. }

另外注明一下UtilTimerStack的push和pop是用来计算调用方法所执行的开始和结束时间,用来做性能测试的。用法如下:

Java代码 
  1. String timerKey = "ActionContextCleanUp_doFilter: ";
  2. UtilTimerStack.setActive(true);
  3. UtilTimerStack.push(timerKey);
  4. //调用要测试的方法。
  5. UtilTimerStack.pop(timerKey);
Java代码  
  1. String timerKey = "ActionContextCleanUp_doFilter: ";
  2. UtilTimerStack.setActive(true);
  3. UtilTimerStack.push(timerKey);
  4. //调用要测试的方法。
  5. UtilTimerStack.pop(timerKey);

ActionContextCleanUp作用的更多相关文章

  1. ActionContextCleanUp

    ActionContextCleanUp作用   延长action中属性的生命周期,包括自定义属性,以便在jsp页面中进行访问,让actionContextcleanup过滤器来清除属性,不让acti ...

  2. struts2框架 转载 精华帖

    一.Struts2简介 参考<JavaEE 轻量级框架应用与开发—S2SH> Struts框架是流行广泛的一个MVC开源实现,而Struts2是Struts框架的新一代产品,是将Strut ...

  3. Struts2 执行流程 以及 Action与Servlet比较 (个人理解)

    上图提供了struts2的执行流程.如下: 1:从客户端发出请求(HTTPServletRequest). 2:请求经过各种过滤器(filter),注:一般情况下,如SiteMesh等其他过滤器要放在 ...

  4. StrutsPrepareAndExecuteFilter的作用

    FilterDispatcher是早期struts2的过滤器,后期的都用StrutsPrepareAndExecuteFilter了,如 2.1.6.2.1.8.StrutsPrepareAndExe ...

  5. Struts2中web.xml里面struts-cleanup作用

    struts2.1.3之后的版本均不需要配置该过滤器 参考: struts-cleanup作用 升级到struts-2.3.14.3之后涉及的改动以及ActionContextCleanUp,Stru ...

  6. if __name__== "__main__" 的意思(作用)python代码复用

    if __name__== "__main__" 的意思(作用)python代码复用 转自:大步's Blog  http://www.dabu.info/if-__-name__ ...

  7. (转载)linux下各个文件夹的作用

    linux下的文件结构,看看每个文件夹都是干吗用的/bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基 ...

  8. github中的watch、star、fork的作用

    [转自:http://www.jianshu.com/p/6c366b53ea41] 在每个 github 项目的右上角,都有三个按钮,分别是 watch.star.fork,但是有些刚开始使用 gi ...

  9. web.xml中welcome-file-list的作用

    今天尝试使用struts2+ urlrewrite+sitemesh部署项目,结果发现welcome-file-list中定义的欢迎页不起作用: <welcome-file-list> & ...

随机推荐

  1. django---ORM之Q查询

    filter 等方法中的关键字参数查询都是一起进行“AND” 的. 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q对象 调用Q from django.db.models import Q ...

  2. Zabbix Windos agent 安装

    系统:Windos 2008 R2 x64 服务:Zabbix_agents_3.0.4.win 一.安装Zabbix_agents_3.0.4.win 1.下载Zabbix_agents_3.0.4 ...

  3. 20165101 实验二 Java面向对象程序设计

    20165101 实验二 Java面向对象程序设计

  4. [CF489D]Unbearable Controversy of Being

    题目大意:求有向图中这种图的数量 从分层图来考虑,这是一个层数为3的图 枚举第一个点能到达的所有点,对他们进行BFS求第三层的点(假装它是BFS其实直接枚举效果一样) 代码: #include< ...

  5. APIGateway网关安全设计

    Spring Cloud里面有个组件 Zuul网关 网关和 过滤器 拦截器很相似 网关可以实现过滤器 拦截器的功能 而且可以实现Nginx的基本功能 反向代理 负载均衡ribbon Nginx是软负载 ...

  6. 基于 CodeIgniter 的各类开源项目大全

    名称:STBlog 介绍:STBlog 是一套由CI中国社区驱动,基于Codeigniter MVC 框架编写的多权限博客系统,轻巧/快速/安全/易拓展/界面友好是它的最大特点. 官方:http:// ...

  7. elasticsearch 拼音搜索

    现在很多公司都开始使用es来做搜索,我们公司目前也有好几个业务部门在用,我主要做商户搜索,为业务部门提供基础支持.上周把呼叫中心的搜索重新整理了下,在新增几个字段后,全量同步发现通过拼音首字母搜索无法 ...

  8. Mac Item2 SSH免密登录Linux 服务器的两种方式

    转自http://blog.csdn.net/jobschen/article/details/52823980 mac ssh登录linux服务器 的两种方式: 个人推荐第二种,zsh方式,只需要把 ...

  9. FckEditor 配置手册中文教程详细说明

    http://www.jb51.net/article/17965.htm 首先,FCKEDITOR的性能是非常好的,用户只需很少的时间就可以载入 FCKEDITOR所需文件.对于其他在线编辑器来说, ...

  10. Java中sleep()与wait()的区别

    第一种解释: 功能差不多,都用来进行线程控制,他们最大本质的区别是:sleep()不释放同步锁,wait()释放同步缩.       还有用法的上的不同是:sleep(milliseconds)可以用 ...