1. 程式人生 > >Struts2:ognl+valueStack

Struts2:ognl+valueStack

一、ognl介紹

OGNL的全稱是Object Graph Navigation Language,即物件導航圖語言。它是一個開源專案,工作在檢視層,其通過簡單一致的表示式語言來讀取合適者Java物件的屬性值,呼叫物件的方法,遍歷整個物件的結構圖,實現欄位型別的轉換。

二、valueStack介紹

ValueStack也就是值棧,簡單的來說,值棧就是框架建立的一個儲存區域,用來儲存Model物件。它具有棧的特性,可以存放多個物件。在檢視頁面中我們也可以使用<s:debug></s:debug>標籤來檢視值棧中的資訊,

三、strust2框架中ognl+valueStack的搭配使用

當Struts2接受一個請求時,會迅速建立ActionContext,ValueStack,action 。然後把action存放進ValueStack,所以action的例項變數可以被OGNL訪問。訪問上下文(Context)中的物件需要使用#符號標註名稱空間,如#application、#session,另外OGNL會設定一個根物件(root物件),在Struts2中根物件就是ValueStack(值棧) 。如果要訪問根物件(即ValueStack)中物件的屬性,則可以省略#名稱空間,直接訪問該物件的屬性即可。

       在struts2中,根物件ValueStack的實現類為OgnlValueStack,該物件不是我們想像的只存放單個值,而是存放一組物件。在OgnlValueStack類裡有一個List型別的root變數,就是使用他存放一組物件 |--request |--application context ------|--OgnlValueStack root變數[action, OgnlUtil, ... ] |--session |--attr |--parameters,在root變數中處於第一位的物件叫棧頂物件。通常我們在OGNL表示式裡直接寫上屬性的名稱即可訪問root變數裡物件的屬性,搜尋順序是從棧頂物件開始尋找,如果棧頂物件不存在該屬性,就會從第二個物件尋找,如果沒有找到就從第三個物件尋找,依次往下訪問,直到找到為止。 大家注意: Struts2中,OGNL表示式需要配合Struts標籤才可以使用。如:<s:property value="name"/>        由於ValueStack(值棧)是Struts 2中OGNL的根物件,如果使用者需要訪問值棧中的物件,在JSP頁面可以直接通過下面的EL表示式訪問ValueStack(值棧)中物件的屬性: ${foo} //獲得值棧中某個物件的foo屬性。如果訪問其他Context中的物件,由於他們不是根物件,所以在訪問時,需要新增#字首。

四、ognl結構

1. 表示式(Expression)

表示式是整個OGNL的核心,所有的OGNL操作都是針對表示式的解析後進行的。表示式會規定此次OGNL操作到底要幹什麼。我們可以看到,在上面的測試中,name、department.name等都是表示式,表示取name或者department中的name的值。OGNL支援很多型別的表示式,之後我們會看到更多。

2. 根物件(Root Object)

  根物件可以理解為OGNL的操作物件。在表示式規定了“幹什麼”以後,你還需要指定到底“對誰幹”。

  在上面的測試程式碼中,user就是根物件。這就意味著,我們需要對user這個物件去取name這個屬性的值(對user這個物件去設定其中的department中的name屬性值)。

3. 上下文環境(Context)

  有了表示式和根物件,我們實際上已經可以使用OGNL的基本功能。例如,根據表示式對根物件進行取值或者設值工作。不過實際上,在OGNL的內部,所有的操作都會在一個特定的環境中執行,這個環境就是OGNL的上下文環境(Context)。說得再明白一些,就是這個上下文環境(Context),將規定OGNL的操作“在哪裡幹”。

  OGNL的上下文環境是一個Map結構,稱之為OgnlContext。上面我們提到的根物件(Root Object),事實上也會被加入到上下文環境中去,並且這將作為一個特殊的變數進行處理,具體就表現為針對根物件(Root Object)的存取操作的表示式是不需要增加#符號進行區分的。

       OgnlContext不僅提供了OGNL的執行環境。在這其中,我們還能設定一些自定義的parameter到Context中,以便我們在進行OGNL操作的時候能夠方便的使用這些parameter。不過正如我們上面反覆強調的,我們在訪問這些parameter時,需要使用#作為字首才能進行。

五、valueStack結構

參考: