原文http://blog.sina.com.cn/s/blog_87216a00010137t0.htmlhtml
一、值棧的簡單定義:安全
(1)簡單的說,值棧是對應每個請求對象的輕量級的數據存儲中心,在這裏統一管理着數據,供Action、Result、Interceptor等Struts2的其餘部分使用,這樣數據被集中管理起來而不凌亂。session
(2)當有請求的時候,Struts2會爲每一個請求建立一個新的值棧,也就是說,值棧和請求是一一對應的,不一樣的請求,值棧也不同, 而值棧封裝了一次請求全部須要操做的相關的數據。app
(3)正是由於值棧和請求的對應關係,所以值棧能保證線程安全的爲每一個請求提供公共的數據存取服務。框架
(4)就是ROOT根對象,ognl訪問值棧不用加任何的訪問前綴,只需action中聲明相應的屬性,而且生成屬性對應的set和get方法,頁面中經過struts2標籤就能夠存放/取出值棧中的值,EL表達式${username}若是沒有加訪問範圍,訪問的也是值棧,這只是最簡單的值棧應用線程
(5)值棧的特色:若是訪問的值棧裏有多個對象,且相同的屬性在多個對象中同時出現,則值棧會按照從棧頂到棧底的順序,尋找第一個匹配的對象。htm
二、actionContext(action上下文)的簡單定義:對象
(1)ActionContext對象,非根對象,是Action運行的上下文,每一個ActionContext是一個基本的容器,包含着Aciton運行須要的數據,好比請求參數,會話等。blog
(2)ActionContext也是線程安全的,每一個線程都有一個獨立的ActionContext,這樣就不用擔憂值棧中值得線程安全問題了。ci
(3)得到ActionContext對象的方式:
第一種,使用ActionContext自身的方法來獲取: ActionContext ctx = ActionContext.getContext();
第二種,使用ActionInvocation來獲取:ActionContext ctx = actionInvocation.getInvocationContext();
(4)ActionContext裏面存儲着不少值:
a:Request的Parameters,請求中的參數,注意這裏的數據是從數據對象中複製來的,所以這裏的數據的變化是不會影響到請求對象裏面的參數的值的。
b:Request的Attribute,請求中的屬性,這裏是一個Map,存放着請求對象的屬性數據,這些數據和請求對象的Attribute是聯動的。
c:Session的Attribute,會話中的助興,這裏是一個Map,存放着會話對象的屬性數據,這些數據和會話對象的attribute是聯動的。
d:Application的Attribute,應用的屬性,這裏是一個Map,存放着應用對象的屬性數據,這些數據和應用對象的attribute是聯動的。
e:attr,在全部的屬性範圍中獲取值,依次搜索page, request, session 和applicaion
(5)ongl表達式取出action上下文中的值:
因爲Struts2框架把OGNLContext設置爲ActionContext,還把表明application、session、request這些對象的Map對象也放到ActionContext中去。
又由於ActionContext爲非根對象,因此OGNL表達式訪問ActionContext(action上下文)裏面的application、session、request、attr對象中的值時,
須要加訪問前綴#,以便告訴OGNL,尋值不是從根對象中,而是從action上下文的其餘對象中尋找
三、再補充一下EL表達式與ognl表達式從值棧與actionContext中取值的方式對比:
(1)EL表達式:
取值棧:
取actionContext:
(2)ognl表達式:
取值棧:
去actionContext: