OGNL(Object-Graph Navigation Language,物件圖導航語言)是一種功能強大的表達式語言,它透過簡潔的語法讓開發者能夠靈活存取物件屬性、呼叫方法、遍歷物件圖結構,並支援型別轉換等進階功能。在 Struts 2 框架中,OGNL 是預設的表達式語言,扮演著資料綁定與視圖渲染的核心角色。
理解 OGNL 必須先掌握其執行環境——OGNL Context。這實際上是一個 Map 結構(由 ognl.OgnlContext 實現),可容納多個 JavaBean 物件,並擁有一個根物件。根物件的屬性可直接以名稱存取,非根物件則需加上 # 前綴(如 #session.msg)。
Struts 2 將 ActionContext 設為 OGNL 上下文,並把值棧 作為根物件放入其中。值棧是一個動態棧結構,支援物件的壓入、彈出與查詢。關鍵特性包括:
# 前綴ActionContext.put(key, value) 放入的資料,存取時必須加 ## 符號:非根物件存取與集合操作#session.msg 相當於 ActionContext.getContext().getSession().getAttribute("msg")persons.{? #this.age > 25}(過濾),persons.{? #this.name == 'pla1'}.{age}[0](投影)#{ 'foo1':'bar1', 'foo2':'bar2' }% 符號:強制表達式求值當標籤屬性為字串型別時,% 強制將其作為 OGNL 表達式求值,類似 JavaScript 的 eval()。例如 <s:property value="%{user.name}"/>。
$ 符號:國際化與配置檔引用reg.agerange=年齡必須在 ${min} 到 ${max} 之間${min}、${max}public class OGNL1 {
public static void main(String[] args) {
Person person = new Person();
person.setName("zhangsan");
try {
Object value = Ognl.getValue("name", person); // 從根物件取得 name 屬性
System.out.println(value); // 輸出: zhangsan
} catch (OgnlException e) {
e.printStackTrace();
}
}
}
class Person {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
Ognl.getValue(expression, root) 會根據表達式從根物件提取值,這是 OGNL 最基礎的用法。
掌握值棧與 OGNL 的互動機制,是精通 Struts 2 資料流向的關鍵。值棧作為根物件簡化了 Action 屬性存取,而 #、%、$ 三大符號則分別解決了非根物件存取、強制求值與配置檔引用三類場景。實戰中善用這些特性,能大幅提升開發效率與程式碼可讀性。