OGNL用於操作ValueStack中的數據。它負責兩件事。第一是在接收HTTP請求時將請求中的字符串轉換成Java中的類型,比如int、String等,並賦值給ValueStack上的JavaBean,第二是在頁面渲染的時候,從ValueStack中獲取屬性,並將Java類型轉換成字符串進行輸出。整個過程如下圖:
(侵權可刪)
在HTTP的請求參數中,可以包含OGNL表達式(這就是當初Struts2爆重大漏洞的原因了)。
user.name=xxx
表示給user屬性中的name屬性進行賦值。name[0]=xxx
,name[1]=xxx
,表示一個數組。user.name=xxx&user.name=yyy
,表示一個List。由於框架只知道user是個列表,但不知道列表中元素的類型,因此需要在ClassName-conversion.properties
文件中配置元素類型。這個文件的內容例如:Element_users=com.example.util.User
user['name']
,表示一個Map,默認Key和Value類型都是String。Key類型可以在ClassName-conversion.properties
中指定,加入Key_user=java.lang.Integer
即可。#{1,2,3
} 表示一個整數的list#{1:"one",2:"two"
} 表示一個mapusers.{? #this.age > 30
} 過濾出年齡在30歲以上的用戶。不過,這種業務邏輯應該在數據庫層面來完成,工程中不推薦使用。@vs@USER
訪問靜態方法。
ClassName-conversion.properties
要和class文件放在同一個目錄中。
對於List、Map對象來說,開發者不能自己初始化List,否則會發生錯誤。List、Map的初始化應該由框架去完成。
PHP中也有類似的語法,而且更加簡潔。個人還是比較喜歡PHP中的參數語法。簡潔明瞭:user[]表示數組,user[xxx]表示map,這種語法比較簡潔。
自定義類型。將HTTP請求中的參數字符串轉換成自定義類型的對象。可以通過繼承StrutsTypeConverter進行實現。
public class CircleTypeConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values, Class toClass) {
...
}
public String convertToString(Map context, Object c) {
...
}
}
實現了轉換器之後需要告訴框架什麼時候使用這個轉換器。在ClassName-conversion.properties
中指定字段的類型轉換器:circle=com.example.CircleTypeConverter
。這樣就能將請求表單中的字符串轉換成Circle對象了。上面的配置只能指定特定表單的特定字段使用我們自己定義的轉換器,如果要讓整個網站中所有的Circle對象都使用CircleTypeConversion,可以在WEB-INF/classes/xwork-conversion.properties
中指定com.example.Circle=com.example.CircleTypeConverter
。
#session['user']
,使用session對象中的user。#request['user']
,使用request對象中的user。
OGNL可以調用方法,默認調用棧頂對象中的方法。語法如下:
<s:property value="testMethod()"/>