天天看點

(五)Struts2——OGNLOGNL

OGNL

一、值棧

我們在struts——helloWorld中的示例程式中,使用了

${productName}

讀取productName 值,實際上該屬性并不在request 等域對象中,而是從值棧中擷取的。

值棧,ValueStack:

可以從ActionContext中擷取值棧對象。

值棧可以分為兩個邏輯部分:

  • Map棧:實際上是OgnlContext類型。也是對ActionContext的一個引用。裡面儲存各種Map:

    requestMap

    ,

    sessionMap

    ,

    applicationMap

    ,

    parametersMap

    ,

    attr

    .
  • 對象棧:實際上是CompoundRoot類型,是一個使用ArrayList定義的棧。裡面儲存着各種和目前Action執行個體相關的對象。是一個資料結構意義的棧。

ValueStack(值棧): 貫穿整個 Action 的生命周期(每個 Action 類的對象執行個體都擁有一個 ValueStack 對象). 相當于一個資料的中轉站. 在其中儲存目前 Action 對象和其他相關對象.

Struts 架構把 ValueStack 對象儲存在名為 “struts.valueStack” 的請求屬性中。

在 ValueStack 對象的内部有兩個邏輯部分:

  • ObjectStack: Struts 把 Action 和相關對象壓入 ObjectStack 中
  • ContextMap: Struts 把各種各樣的映射關系(一些 Map 類型的對象) 壓入 。ContextMap 中. 實際上就是對 ActionContext 的一個引用

Struts 會把下面這些映射壓入 ContextMap 中

  • parameters: 該 Map 中包含目前請求的請求參數
  • request: 該 Map 中包含目前 request 對象中的所有屬性
  • session: 該 Map 中包含目前 session 對象中的所有屬性
  • application:該 Map 中包含目前 application 對象中的所有屬性
  • attr: 該 Map 按如下順序來檢索某個屬性: request, session, application
    (五)Struts2——OGNLOGNL

二、OGNL

在 JSP 頁面上可以可以利用 OGNL(Object-Graph Navigation Language: 對象-圖導航語言) 通路到值棧(ValueStack) 裡的對象屬性。

若希望通路值棧中 ContextMap 中的資料,需要給OGNL表達式加上一個字首字元

#

。如果沒有字首字元#,搜尋将在ObjectStack裡進行。

1. property标簽

Struts 的 property 标簽用來輸出值棧中的一個屬性值.

(五)Struts2——OGNLOGNL

jsp檔案上面需要導入标簽庫:

<%@ taglib prefix="s" uri="/struts-tags" %>
           

2. 讀取ObjectStack裡對象的屬性

  • 想要通路ObjectStack裡對象的屬性。可以使用以下幾種形式之一:
    object.propertyName
    object['propertyName']
    object["propertyName"]
               
  • ObjectStack 裡的對象可以通過一個從零開始的下标來引用。 ObjectStack 裡的棧頂對象可以用 [0] 來引用, 它下面的那個對象可以用 [1] 引用.。若希望傳回棧頂對象的 message 屬性值:

    [0].message

    [0]["message"]

    [0]['message']

    ,結合property标簽,可以寫成:

    <s:property value="[0].message" />

    或者

    <s:property value="message" />

  • 若在指定的對象裡沒有找到指定的屬性, 則到指定對象的下一個對象裡繼續搜尋. 即 [n] 的含義是從第 n 個開始搜尋, 而不是隻搜尋第 n 個對象
  • 若從棧頂對象開始搜尋, 則可以省略下标部分
預設情況下,Action 對象會被Struts2自動的放到值棧的棧頂。

3. 讀取Context Map棧裡面的屬性

若想通路 ContextMap 裡的某個對象的屬性, 可以使用以下幾種形式之一:

#object.propertyName
#object['propertyName']
#object["propertyName"]
           

示例:

  • 傳回 session 中的 code 屬性:

    #session.code

  • 傳回 request 中的 customer 屬性的 name 屬性值:

    #request.customer.name

  • 傳回域對象(按 request, session, application 的順序)的 lastAccessDate 屬性:

    #attr.lastAccessDate

4. 調用字段和方法

可以利用 OGNL 調用

  • 任何一個 Java 類裡的靜态字段或方法.
  • 被壓入到 ValueStack 棧的對象上的公共字段和方法.

預設情況下, Struts2 不允許調用任意 Java 類靜态方法, 需要重新設定

struts.ognl.allowStaticMethodAccess

标記變量的值為 true.

調用靜态字段或方法需要使用如下所示的文法:

  • @[email protected]:

    例如:

    @[email protected]

  • @[email protected](argumentList):

    例如:

    @[email protected]()

調用一個執行個體字段或方法的文法, 其中 object 是 Object Stack 棧裡的某個對象的引用:

  • object.fieldName:

    [0].datePattern

  • object.methodName(argumentList):

    [0].repeat(3, “Hello”);

5. 通路數組類型的屬性

  • 有些屬性将傳回一個對象數組而不是單個對象, 可以像讀取任何其他對象屬性那樣讀取它們。這種數組型屬性的各個元素以逗号分隔, 并且不帶方括号。
  • 可以使用下标通路數組中指定的元素:

    colors[0]

  • 可以通過調用其 length 字段查出給定數組中有多少個元素:

    colors.length

6. 通路List類型的數組

  • 有些屬性将傳回的類型是 java.util.List, 可以像讀取任何其他屬性那樣讀取它們. 這種 List 的各個元素是字元串, 以逗号分隔, 并且帶方括号
  • 可以使用下标通路 List 中指定的元素:

    colors[0]

  • 可以通過調用其 size 方法或專用關鍵字 size 的方法查出給定List 的長度:

    colors.size

    colors.size()

  • 可以通過使用 isEmpty() 方法或專用關鍵字 isEmpty 來得知給定的 List 是不是空.

    colors.isEmpty

    colors.isEmpty()

  • 還可以使用 OGNL 表達式來建立 List, 建立一個 List 與聲明一個 Java 數組是相同的:

    {“Red”, “Black”, “Green”}

7. 通路Map類型的屬性

  • 讀取一個 Map 類型的屬性将以如下所示的格式傳回它所有的鍵值對:
    { key-1=value-1, key-2=value-2,... key-n=value-n,}
               
  • 若希望檢索出某個 Map 的值, 需要使用如下格式:

    map[key]

  • 可以使用

    size

    size()

    得出某個給定的 Map 的鍵值對的個數
  • 可以使用

    isEmpty

    isEmpty()

    檢查某給定 Map 是不是空.
  • 可以使用如下文法來建立一個 Map:
    #{ key-1:value-1, key-2:value-2,... key-n:value-n,}
               

8. 使用EL通路值棧中對象的屬性

<s:property value=“fieldName”>

也可以通過 JSP EL 來達到目的:

${fieldName}

原理: Struts2 将包裝

HttpServletRequest

對象後的

org.apache.struts2.dispatcher.StrutsRequestWrapper

對象傳到頁面上, 而這個類重寫了

getAttribute()

方法.

END.