ActionContextCleanUp作用
延長action中屬性的生命周期,包括自定義屬性,以便在jsp頁面中進行訪問,讓actionContextcleanup過濾器來清除屬性,不讓action自己清除。
??? 為了使用WebWork,我們只需要在web.xml配置FilterDispatcher一個過濾器即可,閱讀一下FilterDispatcher的JavaDoc和源碼,我們可以看到它調(diào)用了:
?finally
?{
????????????ActionContextCleanUp.cleanUp(req);
?}?
在ActionContextCleanUp中,有這樣的代碼:
req.setAttribute(CLEANUP_PRESENT, Boolean.TRUE);?
如果FilterDispatcher檢測到這個屬性,就不會清除ActionContext中的內(nèi)容了,而由ActionContextCleanUp后續(xù)的代碼來清除,保證了一系列的Filter訪問正確的ActionContext.
文檔中提到,如果用到SiteMesh的Filter或者其他類似Filter,那么設(shè)置順序是:
?ActionContextCleanUp filter
?SiteMesh filter
?FilterDispatcher
?所以最后我們的web.xml應(yīng)該類似這樣:
????<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,現(xiàn)在的路徑變成了org.apache.struts2.dispatcher.ActionContextCleanup。
?????那么這個類究竟有什么用處呢?是不是一定要用呢?
?????下面是這個類內(nèi)部的注釋。
?????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或者是現(xiàn)在的StrutsPrepareAndExecuteFilter之前。在調(diào)用完所有過濾器的doFilter方法后,核心過濾器FilterDispatcher或者StrutsPrepareAndExecuteFilter會清空ActionContext,如果其他過濾器要一直使用value stack等struts的特性時,如果不用ActionContextCleanUp的話,便得不到想要的值。
?
?????ActionContextCleanUp 的作用就是上面用粗體標注出來的那一句。它會在doFilter方法里設(shè)置一個計數(shù)器counter的初始值為1,有了這個值,后續(xù)的核心過濾器就不會清 空ActionContext,而是由之前的過濾器也就是ActionContextCleanUp來清空ActionContext。
1. ActionContext
ActionContext是被存放在當前線程中的,獲取ActionContext也是從ThreadLocal中獲取的。所以在執(zhí)行攔截器、 action和result的過程中,由于他們都是在一個線程中按照順序執(zhí)行的,所以可以可以在任意時候在ThreadLocal中獲取 ActionContext。
ActionContext包括了很多信息,比如Session、Application、Request、Locale、ValueStack等,其中 ValueStack可以解析ognl表達式,來動態(tài)獲取一些值,同時可以給表達式提供對象。
?
ActionContext(com.opensymphony.xwork.ActionContext)是Action執(zhí)行時的上下文,上下文可以看 作是一個容器 (其實我們這里的容器就是一個Map而已),它存放的是Action在執(zhí)行時需要用到的對象. 一般情況, 我們的ActionContext都是通過: ActionContext context = (ActionContext) actionContext.get(); 來獲取的.我們再來看看這里的actionContext對象的創(chuàng)建:
static ThreadLocal actionContext = new ActionContextThreadLocal();
ActionContextThreadLocal是實現(xiàn)ThreadLocal的一個內(nèi)部類.ThreadLocal可以命名為"線程局部變量",它為 每一個使用該變量的線程都提供一個變量值的副本,使每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突.這樣,我們 ActionContext里的屬性只會在對應(yīng)的當前請求線程中可見,從而保證它是線程安全的.
通過ActionContext取得HttpSession: Map session = ActionContext.getContext().getSession(); (通過Map模擬HttpServlet的對象,操作更方便)
?
2. ServletActionContext
ServletActionContext(com.opensymphony.webwork. ServletActionContext),這個類直接繼承了我們上面介紹的ActionContext,它提供了直接與Servlet相關(guān)對象訪問的 功能,它可以取得的對象有:
(1)javax.servlet.http.HttpServletRequest : HTTPservlet請求對象?
(2)javax.servlet.http.HttpServletResponse : HTTPservlet相應(yīng)對象?
(3)javax.servlet.ServletContext : Servlet上下文信息?
(4)javax.servlet.ServletConfig : Servlet配置對象?
(5)javax.servlet.jsp.PageContext : Http頁面上下文
如何從ServletActionContext里取得Servlet的相關(guān)對象:
<1>取得HttpServletRequest對象: HttpServletRequest request = ServletActionContext. getRequest();
<2>取得HttpSession對象: HttpSession session = ServletActionContext. getRequest().getSession();
?
3. ServletActionContext和ActionContext聯(lián)系
ServletActionContext和ActionContext有著一些重復(fù)的功能,在我們的Action中,該如何去抉擇呢?我們遵循的原則 是:如果ActionContext能夠?qū)崿F(xiàn)我們的功能,那最好就不要使用ServletActionContext,讓我們的Action盡量不要直接 去訪問Servlet的相關(guān)對象.
注意:在使用ActionContext時有一點要注意: 不要在Action的構(gòu)造函數(shù)里使用ActionContext.getContext(), 因為這個時候ActionContext里的一些值也許沒有設(shè)置,這時通過ActionContext取得的值也許是null;同 樣,HttpServletRequest req = ServletActionContext.getRequest()也不要放在構(gòu)造函數(shù)中,也不要直接將req作為類變量給其賦值。 至于原因,我想是因為前面講到的static ThreadLocal actionContext = new ActionContextThreadLocal(),從這里我們可以看出ActionContext是線程安全的,而 ServletActionContext繼承自ActionContext,所以ServletActionContext也線程安全,線程安全要求每 個線程都獨立進行,所以req的創(chuàng)建也要求獨立進行,所以ServletActionContext.getRequest()這句話不要放在構(gòu)造函數(shù) 中,也不要直接放在類中,而應(yīng)該放在每個具體的方法體中(eg:login()、queryAll()、insert()等),這樣才能保證每次產(chǎn)生對象 時獨立的建立了一個req。
?
4.ActionContextClearUp
ActionContextClearUp其實是Defer ClearUP.作用就是延長action中屬性的生命周期,包括自定義屬性,以便在jsp頁面中進行訪問,讓actionContextcleanup 過濾器來清除屬性,不讓action自己清除。具體看下面的代碼,代碼很簡單:
Java代碼??
另外注明一下UtilTimerStack的push和pop是用來計算調(diào)用方法所執(zhí)行的開始和結(jié)束時間,用來做性能測試的。用法如下:
Java代碼?轉(zhuǎn)載于:https://www.cnblogs.com/sunxucool/archive/2013/06/04/3117193.html
總結(jié)
以上是生活随笔為你收集整理的ActionContextCleanUp作用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Struts2中使用OGNL表达式投影(
- 下一篇: struts升级:FileUploadI