国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Struts2中的valuestack

2019-11-14 22:28:26
字體:
來源:轉載
供稿:網友
Struts2中的valuestack

值棧(ValueStack)    

Struts2將OGNL上下文設置為Struts2中的ActionContext(內部使用的仍然是

OgnlContext),并將值棧設為OGNL的根對象。    

我們知道,OGNL上下文中的根對象可以直接訪問,不需要使用任何特殊的“標記”,

而引用上下文中的其他對象則需要使用“#”來標記。由于值棧是上下文中的根對

象,因此可以直接訪問。那么對于值棧中的對象該如何訪問呢?Struts2提供了一

個特殊的OGNLPRopertyaccessor,它可以自動查找棧內的所有對象(從棧頂到棧

底),直接找到一個具有你所查找的屬性的對象。也就是說,對于值棧中的任何對

象都可以直接訪問,而不需要使用“#”。    

假設值棧中有兩個對象:student和employee,兩個對象都有name屬性,student有

學號屬性number,而employee有薪水屬性salary。employee先入棧,student后入

棧,位于棧頂,那么對于表達式name,訪問的就是student的name屬性,因為

student對象位于棧頂;表達式salary,訪問的就是employee的salary屬性。正如

你所見,訪問值棧中的對象屬性或方法,無須指明對象,也不用“#”,就好像值棧

中的對象都是OGNL上下文中的根對象一樣。這就是Struts2在OGNL基礎上做出的改進。

值棧中的Action實例  

Struts2框架總是把Action實例放在棧頂。因為Action在值棧中,而值棧又是OGNL

中的根,所以引用Action的屬性可以省略“#”標記,這也是為什么我們在結果頁面

中可以直接訪問Action的屬性的原因。

Struts2中的命名對象    

Struts2還提供了一些命名對象,這些對象沒有保存在值棧中,而是保存在

ActionContext中,因此訪問這些對象需要使用“#”標記。這些命名對象都是Map類

型。   

parameters    

用于訪問請求參數。如:#parameters['id']或#parameters.id,相當于調用了

HttpServletRequest對象的getParameter()方法。    

注意,parameters本質上是一個使用HttpServletRequest對象中的請求參數構造的

Map對象,一旦對象被創建(在調用Action實例之前就已經創建好了),它和

HttpServletRequest對象就沒有了任何關系。 

request    

用于訪問請求屬性。如:#request['user']或#request.user,相當于調用了

HttpServletRequest對象的getAttribute()方法。   

session    

用于訪問session屬性。如:#session['user']或#session.user,相當于調用了

HttpSession對象的getAttribute()方法。   

application    

用于訪問application屬性。如:#application['user']或#application.user,相

當于調用了ServletContext的getAttribute()方法。   

attr    

如果PageContext可用,則訪問PageContext,否則依次搜索request、session和

application對象。

以下是轉過來的:先分清楚下ActionContext 、ValueStack 、Stack Context三者

ActionContext

一次Action調用都會創建一個ActionContext

調用:ActionContext context = ActionContext.getContext()

ValueStack

由OGNL框架實現

可以把它簡單的看作一個棧(List)。

Stack Object:放入stack中的對象,一般是action。

Stack Context(map):stack上下文,它包含一系列對象,包括request/session

/attr/application map等。

EL:存取對象的任意屬性,調用對象的方法,遍歷整個對象結…

ActionContext是Action上下文,可以得到requestsession application

ValueStack是值棧 存放表單中的值

Stack Context 棧上下文 也是用來存值的

struts2對OGNL上下文的概念又做了進一步擴充,在struts2中,OGNL上下文通常如

下所示:

|--request

|

|--application

|

context map---|--OgnlValueStack(root) [user, action, OgnlUtil, ... ]

|

|--session

|

|--attr

|

|--parameters

在Struts2中,采用標準命名的上下文(Context)來處理OGNL表達式。處理OGNL

的頂級對象是一個Map(也叫context map),而OGNL在這個context中就是一個頂

級對象(root)。在用法上,頂級對象的屬性訪問,是不需要任何標記前綴的。而其

它非頂級的對象訪問,需要使用#標記。

Struts2框架把OGNL Context設置為我們的ActionContext。并且ValueStack作

為OGNL的根對象。除value stack之外,Struts2框架還把代表application、

session、request這些對象的Map對象也放到ActionContext中去。(這也就是

Struts2建議在Action類中不要直接訪問ServletAPI的原因,他可以通過

ActionContext對象來部分代替這些(Servlet API)功能,以方便對Action類進行

測試!)

Action的實例,總是放到value stack中。因為Action放在stack中,而stack

是root(根對象),所以對Action中的屬性的訪問就可以省略#標記。但是,要訪問

ActionContext中其它對象的屬性,就必須要帶上#標記,以便讓OGNL知道,不是從

根對象,而是從其它對象中去尋找。

那么訪問Action中的屬性的代碼就可以這樣寫

<s:propertyvalue="postalCode"/>

其它ActionContext中的非根對象屬性的訪問要像下面這樣寫:

<s:propertyvalue="#session.mySessionPropKey"/> or

<s:propertyvalue="#session['mySessionPropKey']"/> or

<s:property value="#request['myRequestPropKey']"/>

對Collection的處理,內容就很簡單。

<s:select label="label"name="name" list="{'name1','name2','name3'}"

value="%{'name2'}" />

這是處理List。這個代碼在頁面上建立一個下拉選項,內容是list中的內容,

默認值是name2.

處理map

<s:select label="label"name="name" list="#{'foo':'foovalue',

'bar':'barvalue'}" />

需要注意的是,判斷一個值是否在collection中。我們要使用in或者not in

來處理。

<s:if test="'foo' in{'foo','bar'}">

muhahaha

</s:if>

<s:else>

boo

</s:else>

另外,可以使用通配符來選擇collection對象的子集。

?——所有匹配選擇邏輯的元素

^——只提取符合選擇邏輯的第一個元素

$——只提取符合選擇邏輯的最后一個元素

person.relatives.{? #this.gender == 'male'}

`````````````````````````````````````````````````````````````````````````````````

以下為補充摘錄的一些問題:

提問:在Struts2中,如何使用自身的Tag讀取Action中的變量?

Struts2自身的Tag會根據value中的OGNL表達式,在ValueStack中尋找相應的對

象。因為action在ValueStack的頂部,所以默認情況下,Struts2的Tag中的OGNL表

達式將查找action中的變量。請注意,value中的內容直接是OGNL表達式,無需任

何el的標簽包裝。

例如:<s:property value="user.name" />

提問:在Struts2中,如何使用自身的Tag讀取HttpServletRequest,HttpSession

中的變量?

在上面的知識中,我們知道,Struts2中OGNL的上下文環境中,包含

request,session,application等servlet對象的Map封裝。既然這些對象都在

OGNL的上下文中,那么根據OGNL的基本知識,我們可以通過在表達式前面加上#符

號來對這些變量的值進行訪問。

例如:<s:propertyvalue="%{#application.myApplicationAttribute}" />

<s:propertyvalue="%{#session.mySessionAttribute}" />

<s:property value="%{#request.myRequestAttribute}"/>

<s:propertyvalue="%{#parameters.myParameter}" />

提問:在Struts2中,如何使用JSTL來讀取Action中的變量?

這是一個歷史悠久的問題。因為事實上,很多朋友(包括我在內)是不使用

Struts2自身的標簽庫,而是使用JSTL的,可能因為JSTL標簽庫比較少,簡單易用

的原因吧。

我們知道,JSTL默認是從page,request,session,application這四個Scope逐次

查找相應的EL表達式所對應的對象的值。那么如果要使用JSTL來讀取Action中的變

量,就需要把Action中的變量,放到request域中才行。所以,早在Webwork2.1.X

的年代,我們會編寫一個攔截器來做這個事情的。大致的原理是:在Action執行完

返回之前,依次讀取Action中的所有的變量,并依次調用request.setAttribute()

來進行設置。具體的整合方式,請參考以下這篇文

檔:http://wiki.opensymphony.com/display/WW

/Using+WebWork+and+XWork+with+jsp+2.0+and+JSTL+1.1

不過隨著時代的發展,上面的這種方式,已經不再被推薦使用了。(雖然如此,我

們依然可以學習它的一個解決問題的思路)目前來說,自從Webwork2.2以后,包括

Struts2,都使用另外一種整合方式:對HttpServletRequest進行裝飾。讓我們來

看一下源碼

java代碼

1.public class StrutsRequestWrapper extends HttpServletRequestWrapper {     2.     3.    /**   4.     * The constructor   5.     * @param req The request   6.     */    7.    public StrutsRequestWrapper(HttpServletRequest req) {     8.        super(req);     9.    }    10.    11.    /**  12.     * Gets the object, looking in the value stack if not found  13.     *  14.     * @param s The attribute key  15.     */   16.    public Object getAttribute(String s) {    17.        if (s != null && s.startsWith("javax.servlet")) {    18.             // don't bother with the standardjavax.servlet attributes, we can short-circuit this    19.             // see WW-953 and the forums postlinked in that issue for more info    20.             return super.getAttribute(s);    21.        }    22.    23.        ActionContext ctx = ActionContext.getContext();    24.        Object attribute = super.getAttribute(s);    25.    26.        boolean alreadyIn = false;    27.        Boolean b = (Boolean)ctx.get("__requestWrapper.getAttribute");    28.        if (b != null) {    29.             alreadyIn = b.booleanValue();    30.        }    31.    32.        // note: we don't let # come through or else a request for    33.        // #attr.foo or #request.foo could cause an endless loop    34.        if (!alreadyIn && attribute == null &&s.indexOf("#") == -1) {    35.             try {     36.                 // If not found, then try theValueStack    37.                ctx.put("__requestWrapper.getAttribute", Boolean.TRUE);   38.                 ValueStack stack =ctx.getValueStack();    39.                 if (stack != null) {     40.                     attribute =stack.findValue(s);    41.                 }    42.             } finally {    43.                ctx.put("__requestWrapper.getAttribute", Boolean.FALSE);  44.             }    45.        }    46.         return attribute;    47.    }    48. }   

看到了嘛?這個類會在Struts2初始化的時候,替換HttpServletRequest,運行于

整個Struts2的運行過程中,當我們試圖調用request.getAttribute()的時候,就

會執行上面的這個方法。(這是一個典型的裝飾器模式)在執行上面的方法時,會

首先調用HttpServletRequest中原本的request.getAttribute(),如果沒有找到,

它會繼續到ValueStack中去查找,而action在ValueStack中,所以action中的變量

通過OGNL表達式,就能找到對應的值了。

在這里,在el表達式廣泛使用的今天,JSTL1.1以后,也支持直接使用el表達式。

注意與直接使用struts2的tag的區別,這里需要使用el的表示符號:${}

例如:${user.name}, <c:out value="${department.name}" />

提問:在Struts2中,如何使用Freemarker等模板來讀取Action中的變量以及

HttpServletRequest和HttpSession中的變量?

Freemarker等模板在Struts2中有對應的Result,而在這些Result中,Freemarker

等模板會根據ValueStack和ActionContext中的內容,構造這些模板可識別的

Model,從而使得模板可以以他們各自的語法對ValueStack和ActionContext中的內

容進行讀取。

有關Freemarker對于變量的讀取,可以參考Struts2的官方文檔,非常詳

細:http://struts.apache.org/2.0.14/docs/freemarker.html

設值計算

Struts2中使用OGNL進行設值計算,就是指View層傳遞數據到Control層,并且能夠

設置到相應的Java對象中。這個過程從邏輯上說需要分成兩步來完成:

1. 對于每個請求,都建立一個與相應Action對應的ActionContext作為OGNL的上下

文環境和ValueStack,并且把Action壓入ValueStack

2. 在請求進入Action代碼前,通過某種通用的機制,搜集頁面上傳遞過來的參

數,并調用OGNL相關的代碼,對Action進行設值。

上面的第一個步驟,在處理URL請求時完成,而第二個步驟由struts2內置的攔截器

完成。

原文地址:http://blog.csdn.net/djx123456/article/details/6794581


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 墨玉县| 马边| 丰县| 平昌县| 福鼎市| 白城市| 龙江县| 漾濞| 绥宁县| 塘沽区| 翁源县| 乌鲁木齐市| 海林市| 南平市| 虹口区| 龙南县| 宿松县| 新巴尔虎左旗| 旅游| 宕昌县| 从化市| 大竹县| 灌云县| 惠来县| 图片| 大新县| 中西区| 花莲县| 滕州市| 惠水县| 会宁县| 乾安县| 阿克| 汉中市| 阳高县| 岳普湖县| 曲靖市| 卓资县| 华安县| 封丘县| 景泰县|