(五)Struts2——OGNL

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
    在這裏插入圖片描述

二、OGNL

在 JSP 頁面上可以可以利用 OGNL(Object-Graph Navigation Language: 對象-圖導航語言) 訪問到值棧(ValueStack) 裏的對象屬性。
若希望訪問值棧中 ContextMap 中的數據,需要給OGNL表達式加上一個前綴字符#。如果沒有前綴字符#,搜索將在ObjectStack裏進行。

1. property標籤

Struts 的 property 標籤用來輸出值棧中的一個屬性值. 在這裏插入圖片描述

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.

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

  • @fullyQualifiedClassName@fieldName:
    例如:@java.util.Calendar@DECEMBER
  • @fullyQualifiedClassName@methodName(argumentList):
    例如:@app4.Util@now()

調用一個實例字段或方法的語法, 其中 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.sizecolors.size()
  • 可以通過使用 isEmpty() 方法或專用關鍵字 isEmpty 來得知給定的 List 是不是空. colors.isEmptycolors.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]
  • 可以使用 sizesize() 得出某個給定的 Map 的鍵值對的個數
  • 可以使用 isEmptyisEmpty() 檢查某給定 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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章