Struts2《值棧》

struts2之值棧(value stack)

      衆所周知,Strut 2的Action類通過屬性可以獲得所有相關的值,如請求參數、Action

配置參數、向其他Action傳遞屬性值(通過chain結果)等等。要獲得這些參數值,我

們要做的唯一一件事就是在Action類中聲明與參數同名的屬性,在Struts 2調用Action

類的Action方法(默認是execute方法)之前,就會爲相應的Action屬性賦值。

  要完成這個功能,有很大程度上,Struts 2要依賴於ValueStack對象。這個對象貫

穿整個Action的生命週期(每個Action類的對象實例會擁有一個ValueStack對象)。當

Struts 2接收到一個.action的請求後,會先建立Action類的對象實例,但並不會調用

Action方法,而是先將Action類的相應屬性放到ValueStack對象的頂層節點

(ValueStack對象相當於一個棧)。只是所有的屬性值都是默認的值,如String類型的

屬性值爲null,int類型的屬性值爲0等。

  在處理完上述工作後,Struts 2就會調用攔截器鏈中的攔截器,當調用完所有的攔

截器後,最後會調用Action類的Action方法,在調用Action方法之前,會將ValueStack

對象頂層節點中的屬性值賦給Action類中相應的屬性。大家要注意,在這裏就給我們帶

來了很大的靈活性。也就是說,在Struts 2調用攔截器的過程中,可以改變ValueStack

對象中屬性的值,當改變某個屬性值後,Action類的相應屬性值就會變成在攔截器中最

後改變該屬性的這個值。

  從上面的描述很容易知道,在Struts 2的的Action類可以獲得與屬性同名的參數值

就是通過不同的攔截器來處理的,如獲得請求參數的攔截器是params,獲得Action的配

置參數的攔截器是staticParams等。在這些攔截器內部讀取相應的值,並更新

ValueStack對象頂層節點的相應屬性的值。而ValueStack對象就象一個傳送帶,將屬性

值從一個攔截器傳到了另一個攔截器(當然,在這其間,屬性值可能改變),最後會傳

到Action對象,並將ValueStack對象中的屬性的值終值賦給Action類的相應屬性


個人總結:OGNL中的值棧相當於一個數據的中轉站,或者叫數據的緩衝存儲中心。另外,

OGNL除了有值棧(VS)這個特別的對象外,它的表達式語言也自成一派。

值棧和session都是在ActionContext的全局領域內的,按我個人通俗的說法就是

ActionContext最大,並且ActionContext中包含值棧和session這些全局的容器,

因爲actioncontext是線程級的,那麼session就是線程安全的。


下面介紹如何引用值棧中的對象(又稱屬性或者值,什麼叫法不重要,重要的是知道我們是引用值棧內的東西):

我們在jsp頁面是直接面向值棧操作,所以值棧的內容可以直接用名字來引用。值棧外的如session就要用OGNL語法中的#來操作。

對於值棧來說,struts2有專門的tag叫<s:property >來引用值棧內容,如下例:

<s:property value="artist.bio" />

session是值棧外的(全局的,或稱根級別),所以要用OGNL的#符號表達式來引用session裏的對象,如

<s:property value="#session['artistBio']" />

可以先把一個變量級別升高成爲全局,然後用#符號來引用值,那麼用s:set標籤來做,如

<s:set name="artistName" value="artist.name" /> =====》級別提高了哦,YEAH!!

<s:set name="artistBio" value="artist.bio" /> ======》老子級別也高了,YEAH!!
<b>Album Title :</b> <s:property value="title" /> <br>
<b>Artist Name :</b> <s:property value="#artistName" />
<br> <b>Artist Bio :</b> <s:property value="#artistBio" /> ===》級別高了,不在值棧內就不能直接引用了。。。。。需要加#號

假如想讓對象不但級別高了(全局的)在整個session週期內持久,就要加上scope,如

<s:set name="artistName" value="artist.name" scope="session" />

<s:set name="artistBio" value="artist.bio" scope="session" />
<b>Album Title :</b> <s:property value="title" /> <br>
<b>Artist Name :</b> <s:property value="#session['artistName']" /> <br>
<b>Artist Bio :</b> <s:property value="#session['artistBio']" /> <br>
下面還有push標籤,用來把對象放到值棧頂端:
<b>Album Title :</b> <s:property value="title" /> <br>
<s:push value="artist">
<b>Artist Name :</b> <s:property value="name" /> <br>
<b>Artist Bio :</b> <s:property value="bio" /> <br>
</s:push>
那麼<s:bean>這個標籤,用來在頁面實例化一個bean放在值棧中,它的生存週期就是到了</s:bean>爲止就結束了,所以說假如要用<s:property>這個標籤來引用該bean的屬性的話,一定要在<s:bean>和</s:bean>標籤之中用。如下面例子:
<s:bean name="vaannila.CurrencyConverter">
    <s:param name="dollars" value="100" />
100Dollars =
<s:property value="rupees" />
Rupees
</s:bean>
那麼假如在bean標籤之外引用呢,因爲這時候這個bean的生命週期結束了,已經不在值棧內了,所以要用的話,需要事先在前面bean的聲明地方加上一個變量聲明,使其成爲全局的對象,然後再像引用session變量那樣的方式來引用它,如下例:
<s:bean name="vaannila.CurrencyConverter" var="converter">
<s:param name="dollars" value="100"></s:param>
</s:bean>
100 Dollars =
<s:property value="#converter.rupees" />
Rupees

發佈了29 篇原創文章 · 獲贊 18 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章