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代碼??
另外注明一下UtilTimerStack的push和pop是用來計算調用方法所執行的開始和結束時間,用來做性能測試的。用法如下:
Java代碼?轉載于:https://www.cnblogs.com/sunxucool/archive/2013/06/04/3117193.html
總結
以上是生活随笔為你收集整理的ActionContextCleanUp作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Struts2中使用OGNL表达式投影(
- 下一篇: struts升级:FileUploadI