`
jveqi
  • 浏览: 324093 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ActionContextCleanUp

 
阅读更多

 延长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代码
public void doFilter(...){  
 
  ...  
  try{  
    ...  
    //继续执行所配置的chain中的Filter  
    chain.doFilter(request, response);  
  }finally{  
  //保证在所有动作执行完之后,调用cleanUp  
    ...  
    cleanUp(request);  
  }  
}  
 
protected static void cleanUp(ServletRequest req) {  
 
  ...  
  ActionContext.setContext(null);//清除ActionContext实例  
  Dispatcher.setInstance(null);//清除Dispatcher实例(Dispatcher主要是完成将url解析成对应的Action)  

Java代码 
public void doFilter(...){ 
 
  ... 
  try{ 
    ... 
    //继续执行所配置的chain中的Filter 
    chain.doFilter(request, response); 
  }finally{ 
  //保证在所有动作执行完之后,调用cleanUp 
    ... 
    cleanUp(request); 
  } 

 
protected static void cleanUp(ServletRequest req) { 
 
  ... 
  ActionContext.setContext(null);//清除ActionContext实例 
  Dispatcher.setInstance(null);//清除Dispatcher实例(Dispatcher主要是完成将url解析成对应的Action) 

 
另外注明一下UtilTimerStack的push和pop是用来计算调用方法所执行的开始和结束时间,用来做性能测试的。用法如下:
Java代码
String timerKey = "ActionContextCleanUp_doFilter: ";  
 
UtilTimerStack.setActive(true);  
 
UtilTimerStack.push(timerKey);  
//调用要测试的方法。  
UtilTimerStack.pop(timerKey); 
Java代码 
String timerKey = "ActionContextCleanUp_doFilter: "; 
 
UtilTimerStack.setActive(true); 
 
UtilTimerStack.push(timerKey); 
//调用要测试的方法。 
UtilTimerStack.pop(timerKey); 

分享到:
评论

相关推荐

    三大框架面试题

    2. 请求通过一系列过滤器,包括可选的ActionContextCleanUp过滤器,它有助于与其他框架如SiteMesh的集成。 3. FilterDispatcher被调用,由ActionMapper决定是否需要调用特定的Action。 4. ActionProxy通过...

    pb 数据库struts2 课堂讲稿

    `ActionContextCleanUp`在集成其他插件时特别有用,它负责清理ActionContext的相关数据。 4. **FilterDispatcher**:过滤器链中的`FilterDispatcher`是Struts2的核心组件,它负责查找并调用对应的ActionMapper。 5...

    Struts2_OGNL 笔记

    charset=utf-8"`,并配置web.xml中的`ActionContextCleanUp`过滤器以确保请求处理时的编码一致性。 5. ActionContextCleanUp过滤器的作用: `ActionContextCleanUp`过滤器是Struts2的一部分,它用于清理...

    struts2源代码分析

    请求在Struts2框架中的处理流程始于Filter链,其中Filter主要包括`ActionContextCleanUp`和`FilterDispatcher`。`ActionContextCleanUp`的作用是清理当前线程的`ActionContext`,确保每个请求的上下文环境独立。`...

    struts2工作原理及源码分析学习笔记

    - 请求经过ActionContextCleanUp过滤器,清理上下文。 - FilterDispatcher利用ActionMapper确定Action。 - ActionProxy根据ActionMapping和ConfigurationManager找到Action类。 - ActionInvocation实例化并调用...

    JAVA三大框架面试题(2)参照.pdf

    接着,一系列过滤器(包括可选的ActionContextCleanUp过滤器)处理请求,直到FilterDispatcher被调用。FilterDispatcher通过ActionMapper确定是否需要调用特定的Action。如果需要,ActionProxy根据Configuration ...

    Struts2源码分析

    2. **请求通过ActionContextCleanUp**:请求首先经过`ActionContextCleanUp`过滤器,清理上一个请求可能留下的数据。 3. **FilterDispatcher处理请求**:接下来,请求被`FilterDispatcher`捕获,`FilterDispatcher`...

    JAVA三大框架面试题.pdf

    - 请求通过一系列过滤器,包括可选的ActionContextCleanUp过滤器。 - FilterDispatcher被调用,它依赖ActionMapper来判断是否需要调用特定的Action。 - 如果ActionMapper确定需要调用Action,FilterDispatcher将...

    Struts2的运行流程

    在这个过程中,`ActionContextCleanUp`过滤器会清理Action上下文,而`FilterDispatcher`则负责请求的调度。 5. `FilterDispatcher`将请求转发给`ActionMapper`,`ActionMapper`的作用是解析请求URL,判断是否需要...

    spring2.5.4+hibernate3.2.6+struts2+jbpm3.2.2配置方法

    `FilterDispatcher`是Struts2的核心过滤器,拦截所有请求并进行处理,而`ActionContextCleanUp`则用于清理Action上下文,确保每次请求都有独立的环境。 4. **jbpm3.2.2**: - jbpm是一个流程管理框架,用于定义、...

    java中三大框架和项目模拟面试题目[参考].pdf

    2. 请求经过一系列过滤器,包括ActionContextCleanUp,为与其他框架集成提供便利。 3. FilterDispatcher作为核心控制器被调用,它会询问ActionMapper决定是否需要调用某个Action。 4. ActionMapper确定后,...

    struts2工作流程

    Struts2中默认包含的过滤器有ActionContextCleanUp,这是一个可选过滤器,主要作用是在请求结束时清理与请求相关的上下文环境,这对于框架间的集成特别有帮助,例如在使用SiteMesh插件时。除此之外,还有其他自定义...

    S2SH三大框架面试题

    - 请求通过一系列过滤器,包括可选的`ActionContextCleanUp`过滤器,它有助于与其他框架如SiteMesh的集成。 - `FilterDispatcher`被调用,它询问`ActionMapper`决定是否需要调用特定`Action`。 - 如果需要,`...

    专题资料(2021-2022年)struts2核心工作流程与原理.doc

    过滤器按照定义的顺序执行,`ActionContextCleanUp`通常用于清理或初始化Action上下文,`SiteMesh`等过滤器可能处理视图层面的任务,而`FilterDispatcher`则作为控制器的核心,处理请求的路由和调度。 3. **...

    OGNL表达式详解[定义].pdf

    例如,设置JSP页面的编码为`utf-8`,并在`web.xml`中使用`ActionContextCleanUp`过滤器来清理请求和响应的编码。过滤器配置如下: ```xml &lt;filter-name&gt;struts-cleanup &lt;filter-class&gt;org.apache.struts2....

    ognl+标签知识点.pdf

    在使用OGNL之前,需要在`web.xml`配置文件中添加`ActionContextCleanUp`过滤器,确保每个请求结束后清理ActionContext,防止跨请求污染。配置如下: ```xml &lt;filter-name&gt;struts-cleanup &lt;filter-class&gt;org....

    JAVA三大框架面试题(2)[定义].pdf

    2. 请求通过一系列过滤器,包括可选的`ActionContextCleanUp`过滤器,该过滤器有助于与其他框架集成。 3. `FilterDispatcher`被调用,它询问`ActionMapper`来决定是否需要执行特定的Action。 4. 如果需要执行Action...

    Struts2 简介

    ActionContextCleanUp过滤器的作用是清理Action中的属性,确保它们在JSP页面中仍然可访问,提供了一种跨请求共享数据的方法。通过这样的设计,Struts2提供了一个高度可定制和可扩展的框架,使得开发者能够更加专注于...

    Struts2的工作原理和流程

    2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 3 接着FilterDispatcher被调用,...

Global site tag (gtag.js) - Google Analytics