OGNL(Object-Graph Navigation Language,對象圖導航語言) 是一種功能強大的表達式語言,Struts 2 預設採用它作為視圖層的表達式引擎。優勢在於:
user.getAddress().getCity())@java.lang.Math@PI)price=100, discount=0.8, totalPrice())ActionContext 與 ValueStackOgnlContext)本質是一個 Map,包含一個根對象與多個命名對象。訪問根對象屬性無需前綴,訪問命名對象需加 #。
ActionContext (OGNL Context Map)
├── ValueStack (Root Object) ← 默認根,存放 Action 實例、領域模型等
│ ├── [0] Action Instance (Top)
│ ├── [1] Other Model Objects
│ └── ...
├── #request → HttpServletRequest 屬性 Map
├── #session → HttpSession 屬性 Map
├── #application → ServletContext 屬性 Map
├── #parameters → 請求參數 Map (請求創建時快照,與 Request 解耦)
├── #attr → 依序搜尋 PageContext→Request→Session→Application
└── #... → 其他自定義命名對象
關鍵規則:
user.name)#(#session.userId)ActionContext 設為 OGNL 上下文,並把 ValueStack 設為根對象| 符號 | 用途 | 範例 |
|---|---|---|
# | 訪問非根對象(命名對象) | #request.foo、#parameters.id |
% | 強制在字串屬性中解析 OGNL 表達式(類似 eval) | <s:property value="%{getText('key')}"/> |
$ | 國際化資源檔、struts.xml 中引用 OGNL | ${min}、${max}(驗證訊息中) |
<!-- 屬性鏈 -->
<s:property value="user.address.city"/>
<!-- 方法調用 -->
<s:property value="user.getFullName()"/>
<!-- 靜態屬性/方法 -->
<s:property value="@java.lang.Math@PI"/>
<s:property value="@com.example.Constants@APP_NAME"/>
<s:property value="@java.util.Calendar@getInstance()"/>
<!-- 建構子 -->
<s:property value="new com.example.User('John', 25).name"/>
<!-- List/Array -->
<s:property value="users[0].name"/>
<!-- Map -->
<s:property value="userMap['key1']"/>
<s:property value="userMap.keys"/>
<s:property value="userMap.values"/>
<!-- 投影與選擇 -->
<!-- 所有及格學生 -->
<s:property value="students.{? #this.score >= 60}"/>
<!-- 及格學生的姓名集合 -->
<s:property value="students.{? #this.score >= 60}.{name}"/>
<!-- 第一個及格學生姓名 -->
<s:property value="students.{^ #this.score >= 60}.{name}"/>
<!-- 最後一個及格學生姓名 -->
<s:property value="students.{$ #this.score >= 60}.{name}"/>
<!-- 階乘 -->
<s:property value="#fact = :[#this==1?1:#this*#fact(#this-1)], #fact(5)"/>
[0] / top → 棧頂對象(當前 Action)[1] → 第二個對象vs1 → 命名值棧引用(罕用)<s:property value="[1].someProperty"/> <!-- 訪問棧中第二個對象屬性 -->
ActionContext.getContext() 獲取 Map,利於單元測試。%{...} 強制解析,避免字串字面值被誤當作純文字。