OGNL(Object Graph Navigation Language )在Struts2.0中得到了普遍的應用,我們經常用它來訪問Action中的properties,下面是一些常見的例子:
<s:property value="#session.mySessionPropKey"/> <s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" /> <s:if test="'foo' in {'foo','bar'}"> muhahaha </s:if> <s:else> boo </s:else>
其中我們用的比較複雜的應該就是一些屬性之間的包含和父子關係了,還有就是我們用到的比較多的#取值符號和%{}值運算符號。
實際工作過程中,遇到如下一個比較抽象的問題,把這裏的經驗分享給大家。先看下面的一段代碼:
<s:iterator status="stat" value="destObjects"> <tr> <s:iterator value="visibleColumns"> <td> <s:property value="destObjects[%{#stat.index}].%{fieldDefName}" /> </td> </s:iterator> </tr> </s:iterator>
這裏的destObjects是一個List變量,裏面包含有多個DestObject對象;visibleColumns也是許多個VisibleColumn對象的List集合,VisibleColumn擁有一個重要的屬性fieldDefName,表達式"VisibleColumn.fieldDefName"的值又是DestObject的一個屬性名稱。
這裏的關係比較混亂,不過仔細看看,應該就能明白其中的關係。這種模型也是我們在日常數據庫結構設計中常常用到的,即一個定義表用來描述所有字段性質,而這些字段事實上又組成了一張或多張實用表。
通過以上Struts頁面代碼,我卻得不到任何結果。爲了尋找最終的解決途徑,我查詢了多方面的資料,也試過了許多種方式,比如:
<s:property value="destObjects[%{#stat.index}].%{fieldDefName}" /> <!-- OR --> <s:property value="%{destObjects[#stat.index].%{fieldDefName}}" /> <!-- OR --> <s:property value="%{fieldDefName}" /> <!-- OR --> <s:iterator value="destObjects" id="do"> <s:iterator value="visibleColumns" id="vc"> <s:property value="#do.%{vc.fieldDefName}"/> </s:iterator> </s:iterator>
可惜,一切都是徒勞。OGNL是一個比較抽象混雜的語言,有時候多一個%或者#可能意義就不一樣了。
最後給出一個正解,在我看來只是一個"["符號的作用,卻改變了輸出的結果:
<s:iterator id="do" value="destObjects"> <tr> <s:iterator value="visibleColumns"> <td> <s:property value="%{#do[fieldDefName]}"/> </td> </s:iterator> </tr> </s:iterator>