OGNL在Struts2中的應用

要談OGNL在Struts2中的應用,首先得明白OGNL到底是什麼


OGNL 的歷史

OGNL 最初是爲了能夠使用對象的屬性名來建立 UI 組件 (component) 和 控制器 (controllers) 之間的聯繫,簡單來說就是:視圖 與 控制器 之間數據的聯繫。後來爲了應付更加複雜的數據關係,Drew Davidson 發明了一個被他稱爲 KVCL(Key-Value Coding Language) 的語言。 Luke 參與進來後,用 ANTLR 來實現了該語言,並給它取了這個新名字,他後來又使用 JavaCC 重新實現了該語言。目前 OGNL 由 Drew 來負責維護。目前很多項目中都用到了 OGNL,其中不乏爲大家所熟知的,例如幾個流行的 web 應用框架:WebWork【當然struts2也可以說是WebWork升級版】,Tapestry 等。


什麼是 OGNL?

OGNL 是 Object-Graph Navigation Language 的縮寫,從語言角度來說:它是一個功能強大的表達式語言,用來獲取和設置 java 對象的屬性 , 它旨在提供一個更高抽象度語法來對 java 對象圖進行導航,OGNL 在許多的地方都有應用,例如: 

1)作爲 GUI 元素(textfield,combobox, 等)到模型對象的綁定語言。 

2)數據庫表到 Swing 的 TableModel 的數據源語言。 

3)web 組件和後臺 Model 對象的綁定語言 (WebOGNL,Tapestry,WebWork,WebObjects) 。 

4)作爲 Jakarata Commons BeanUtils 或者 JSTL 的表達式語言的一個更具表達力的替代語言。 


另外,java 中很多可以做的事情,也可以使用 OGNL 來完成,例如:列表映射和選擇。對於開發者來說,使用 OGNL,可以用簡潔的語法來完成對 java 對象的導航。通常來說:通過一個“路徑”來完成對象信息的導航,這個“路徑”可以是到 java bean 的某個屬性,或者集合中的某個索引的對象,等等,而不是直接使用 get 或者 set 方法來完成




OGNL 的基本語法

OGNL 表達式一般都很簡單。雖然 OGNL 語言本身已經變得更加豐富了也更強大了,但是一般來說那些比較複雜的語言特性並未影響到 OGNL 的簡潔:簡單的部分還是依然那麼簡單。比如要獲取一個對象的 name 屬性,OGNL 表達式就是 name, 要獲取一個對象的 headline 屬性的 text 屬性,OGNL 表達式就是 headline.text 。 OGNL 表達式的基本單位是“導航鏈”,往往簡稱爲“鏈”。最簡單的鏈包含如下部分:

表達式組成部分      示例 

屬性名稱           如上述示例中的 name 和 headline.text 

方法調用           hashCode() 返回當前對象的哈希碼。 

數組元素           listeners[0] 返回當前對象的監聽器列表中的第一個元素。 


所有的 OGNL 表達式都基於當前對象的上下文來完成求值運算,鏈的前面部分的結果將作爲後面求值的上下文。你的鏈可以寫得很長,例如:

name.toCharArray()[0].numericValue.toString() 


上面的表達式的求值步驟: 

提取根 (root) 對象的 name 屬性。 

調用上一步返回的結果字符串的 toCharArray() 方法。 

提取返回的結果數組的第一個字符。 

獲取字符的 numericValue 屬性,該字符是一個 Character 對象,Character 類有一個 getNumericValue() 方法。 

調用結果 Integer 對象的 toString() 方法。 

上面的例子只是用來得到一個對象的值,OGNL 也可以用來去設置對象的值。當把上面的表達式傳入 Ognl.setValue() 方法將導致 InappropriateExpressionException,因爲鏈的最後的部分(toString())既不是一個屬性的名字也不是數組的某個元素。瞭解了上面的語法基本上可以完成絕大部分工作了。


OGNL 表達式

1)常量:字符串:“ hello ” 字符:‘ h ’ 數字:除了像 java 的內置類型 int,long,float 和 double,Ognl 還有如例:

0.01B,相當於 java.math.BigDecimal,使用’ b ’或者’ B ’後綴。 100000H,相當於 java.math.BigInteger,使用’ h ’ 或 ’ H ’ 後綴。

2)屬性的引用例如:user.name

3)變量的引用例如:#name

4)靜態變量的訪問使用 @class@field

5)靜態方法的調用使用 @class@method(args), 如果沒有指定 class 那麼默認就使用 java.lang.Math.

6)構造函數的調用例如:new java.util.ArrayList();

其它的 Ognl 的表達式可以參考 Ognl 的語言手冊。 



OGNL的性能


OGNL,或者說表達式語言的性能主要又兩方面來決定,一個就是對表達式的解析 (Parser),另一個是表達式的執行,OGNL 採用 javaCC 來完成 parser 的實現,在 OGNL 2.7 中又對 OGNL 的執行部分進行了加強,使用 javasisit 來 JIT(Just-In-Time) 的生成 byte code 來完成表達式的執行。 Ognl 給這個功能的名字是:OGNL Expression Compilation 。基本的使用方法是:

SimpleObject root = new SimpleObject(); 

 OgnlContext context =  (OgnlContext) Ognl.createDefaultContext(null); 

 Node node =  (Node) Ognl.compileExpression(context, root, "user.name"); 

 String userName = (String)node.getAccessor().get(context, root); 

實踐證明:OGNL 非常接近 java 直接調用的時間。



 

表達式語言主要有以下幾大好處:

1)避免(MyType) request.getAttribute()和myBean.getMyProperty()之類的語句,使頁面更簡潔; 

2)支持運算符(如+-*/),比普通的標誌具有更高的自由度和更強的功能; 

3)簡單明瞭地表達代碼邏輯,使用代碼更可讀與便於維護。 


Struts 2中的表達式語言

Struts 2支持以下幾種表達式語言:

1)OGNL(Object-Graph Navigation Language),可以方便地操作對象屬性的開源表達式語言; 

2)JSTL(JSP Standard Tag Library),JSP 2.0集成的標準的表達式語言; 

3)Groovy,基於Java平臺的動態語言,它具有時下比較流行的動態語言(如Python、Ruby和Smarttalk等)的一些起特性; 

4)Velocity,嚴格來說不是表達式語言,它是一種基於Java的模板匹配引擎,具說其性能要比JSP好。 


Struts 2默認的表達式語言是OGNL,原因是它相對其它表達式語言具有下面幾大優勢:

支持對象方法調用,如xxx.doSomeSpecial(); 

支持類靜態的方法調用和值訪問,表達式的格式爲@[類全名(包括包路徑)]@[方法名 |  值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME; 

支持賦值操作和表達式串聯,如price=100, discount=0.8, calculatePrice(),這個表達式會返回80; 

訪問OGNL上下文(OGNL context)和ActionContext; 

操作集合對象。 





Struts2中ONGL的使用示例

index.html


Html代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;"><html>  
  2.     <head>  
  3.          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
  4.         <meta http-equiv="refresh" content="0; url=ognl.action" />  
  5.     </head>  
  6. </html></span></span>  


 User.java


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.web.action;  
  2.   
  3. import java.util.Date;  
  4.   
  5.   
  6. public class User {  
  7.     private Integer id;  
  8.     private String loginname;  
  9.     private Double score;  
  10.     private Boolean gender;  
  11.     private Character cha;  
  12.     private Date birthday;  
  13.       
  14.     public User(){}  
  15.       
  16.     public User(Integer id, String loginname, Double score, Boolean gender,  
  17.             Character cha, Date birthday) {  
  18.         this.id = id;  
  19.         this.loginname = loginname;  
  20.         this.score = score;  
  21.         this.gender = gender;  
  22.         this.cha = cha;  
  23.         this.birthday = birthday;  
  24.     }  
  25.     public Integer getId() {  
  26.         return id;  
  27.     }  
  28.     public void setId(Integer id) {  
  29.         this.id = id;  
  30.     }  
  31.     public String getLoginname() {  
  32.         return loginname;  
  33.     }  
  34.     public void setLoginname(String loginname) {  
  35.         this.loginname = loginname;  
  36.     }  
  37.     public Double getScore() {  
  38.         return score;  
  39.     }  
  40.     public void setScore(Double score) {  
  41.         this.score = score;  
  42.     }  
  43.     public Boolean getGender() {  
  44.         return gender;  
  45.     }  
  46.     public void setGender(Boolean gender) {  
  47.         this.gender = gender;  
  48.     }  
  49.     public Character getCha() {  
  50.         return cha;  
  51.     }  
  52.     public void setCha(Character cha) {  
  53.         this.cha = cha;  
  54.     }  
  55.     public Date getBirthday() {  
  56.         return birthday;  
  57.     }  
  58.     public void setBirthday(Date birthday) {  
  59.         this.birthday = birthday;  
  60.     }  
  61.   
  62.     public String info() {  
  63.         return "User [birthday=" + birthday + ", cha=" + cha + ", gender="  
  64.                 + gender + ", id=" + id + ", loginname=" + loginname  
  65.                 + ", score=" + score + "]";  
  66.     }  
  67. }</span></span>  


 OGNLAction.java


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.web.action;  
  2.   
  3.   
  4. import java.util.ArrayList;  
  5. import java.util.Date;  
  6. import java.util.HashMap;  
  7. import java.util.LinkedHashSet;  
  8. import java.util.List;  
  9. import java.util.Map;  
  10. import java.util.Set;  
  11.   
  12. import org.apache.struts2.ServletActionContext;  
  13.   
  14. import com.opensymphony.xwork2.ActionContext;  
  15. import com.opensymphony.xwork2.ActionSupport;  
  16.   
  17. public class OGNLAction extends ActionSupport {  
  18.     private static final long serialVersionUID = -2554018432709689579L;  
  19.     private String loginname;  
  20.     private String pwd;  
  21.     private User user;  
  22.     private Set<String> courseSet;  
  23.     private List<String> list;  
  24.     private Map<String,String> map;  
  25.     private List<User> userList;  
  26.       
  27.       
  28.     public String execute() throws Exception{  
  29.         this.loginname = "xkkkkkkkkkkkkkkkkkkkkkkkk";  
  30.         this.user = new User(123"wrr"88.9true'B'new Date());  
  31.         this.courseSet = new LinkedHashSet<String>();  
  32.         this.courseSet.add("corejava");  
  33.         this.courseSet.add("JSP/Servlet");  
  34.         this.courseSet.add("S2SH");  
  35.           
  36.         this.list = new ArrayList<String>(this.courseSet);  
  37.         this.map = new HashMap<String, String>();  
  38.         this.map.put("x""xxx");  
  39.         this.map.put("y""yyy");  
  40.         this.map.put("z""zzz");  
  41.           
  42.           
  43.         ActionContext context = ActionContext.getContext();  
  44.         context.put("uname""cheney");  
  45.         context.put("inte", Integer.valueOf(888888));  
  46.         context.put("user2"new User(123"xxk"88.9true'B'new Date()));  
  47.           
  48.           
  49.         this.userList = new ArrayList<User>();  
  50.         this.userList.add(new User(1"zs"48.9true'D'new Date()));  
  51.         this.userList.add(new User(2"ls"68.1true'C'new Date()));  
  52.         this.userList.add(new User(3"ww"78.2false'B'new Date()));  
  53.         this.userList.add(new User(4"zl"88.3true'A'new Date()));  
  54.           
  55.         //-----------------------------------------------------------------  
  56.         //推薦方式:不會跟Servlet API耦合  
  57.         context.put("reqAtt""往ActionContext中put的屬性");  
  58.         context.getSession().put("sesAtt""往ActionContext.getSession()中put的屬性");  
  59.         context.getApplication().put("appAtt""往ActionContext.getApplication()中put的屬性");  
  60.           
  61.         ServletActionContext.getRequest().setAttribute("reqAtt2""Request作用域中的屬性");  
  62.         ServletActionContext.getRequest().getSession().setAttribute("sesAtt2""Session作用域中的屬性");  
  63.         ServletActionContext.getServletContext().setAttribute("appAtt2""Application作用域中的屬性");  
  64.           
  65.         return SUCCESS;  
  66.     }  
  67.       
  68.       
  69.     public String getAppName(){  
  70.         return "這是OGNL的使用示例代碼";  
  71.     }  
  72.       
  73.     public String getLoginname() {  
  74.         return loginname;  
  75.     }  
  76.     public void setLoginname(String loginname) {  
  77.         this.loginname = loginname;  
  78.     }  
  79.     public String getPwd() {  
  80.         return pwd;  
  81.     }  
  82.     public void setPwd(String pwd) {  
  83.         this.pwd = pwd;  
  84.     }  
  85.   
  86.     public User getUser() {  
  87.         return user;  
  88.     }  
  89.   
  90.     public void setUser(User user) {  
  91.         this.user = user;  
  92.     }  
  93.   
  94.     public Set<String> getCourseSet() {  
  95.         return courseSet;  
  96.     }  
  97.   
  98.     public void setCourseSet(Set<String> courseSet) {  
  99.         this.courseSet = courseSet;  
  100.     }  
  101.   
  102.     public List<String> getList() {  
  103.         return list;  
  104.     }  
  105.   
  106.     public void setList(List<String> list) {  
  107.         this.list = list;  
  108.     }  
  109.   
  110.     public Map<String, String> getMap() {  
  111.         return map;  
  112.     }  
  113.   
  114.     public void setMap(Map<String, String> map) {  
  115.         this.map = map;  
  116.     }  
  117.   
  118.     public List<User> getUserList() {  
  119.         return userList;  
  120.     }  
  121.   
  122.     public void setUserList(List<User> userList) {  
  123.         this.userList = userList;  
  124.     }  
  125.       
  126. }</span></span>  

 

src/struts.xml


Xml代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;"><?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.1.7.dtd">  
  5.   
  6. <struts>  
  7.     <!-- 請求參數的編碼方式 -->  
  8.     <constant name="struts.i18n.encoding" value="UTF-8"/>  
  9.     <!-- 指定被struts2處理的請求後綴類型。多個用逗號隔開 -->  
  10.     <constant name="struts.action.extension" value="action,do,go,xkk"/>  
  11.     <!-- 當struts.xml改動後,是否重新加載。默認值爲false(生產環境下使用),開發階段最好打開  -->  
  12.     <constant name="struts.configuration.xml.reload" value="true"/>  
  13.     <!-- 是否使用struts的開發模式。開發模式會有更多的調試信息。默認值爲false(生產環境下使用),開發階段最好打開  -->  
  14.     <constant name="struts.devMode" value="false"/>  
  15.     <!-- 設置瀏覽器是否緩存靜態內容。默認值爲true(生產環境下使用),開發階段最好關閉  -->  
  16.     <constant name="struts.serve.static.browserCache" value="false" />  
  17.     <!-- 是否允許在OGNL表達式中調用靜態方法,默認值爲false -->  
  18.     <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>  
  19.       
  20.     <!-- 指定由spring負責action對象的創建   
  21.     <constant name="struts.objectFactory" value="spring" />  
  22.     -->  
  23.     <!-- 是否開啓動態方法調用 -->  
  24.     <constant name="struts.enable.DynamicMethodInvocation" value="false"/>  
  25.       
  26.     <package name="my" extends="struts-default" namespace="/">  
  27.         <action name="ognl" class="com.javacrazyer.web.action.OGNLAction">  
  28.             <result>/ognl_info.jsp</result>  
  29.         </action>  
  30.     </package>  
  31.       
  32. </struts></span></span>  

 

ognl_info.jsp


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%@ taglib uri="/struts-tags" prefix="s" %>  
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5.   <head>  
  6.     <title>OGNL的使用</title>  
  7.   </head>  
  8.   <body>  
  9. <h3>OGNL的使用</h3><hr/>  
  10.  訪問Action中的普通屬性: <s:property value="loginname"/><br/>  
  11.  訪問Action中的對象屬性: <s:property value="user.birthday"/><br/>  
  12.  訪問Action中的Set屬性: <s:property value="courseSet.toArray()[0]"/><br/>  
  13.  訪問Action中的List屬性: <s:property value="list[0]"/><br/>  
  14.  訪問Action中的Map屬性的鍵: <s:property value="map.keys.toArray()[1]"/><br/>  
  15.  訪問Action中的Map屬性的值: <s:property value="map.values.toArray()[1]"/><br/>  
  16. 訪問Action中的Map屬性的指定鍵對應的值: <s:property value="map['z']"/><br/>   
  17. 訪問Action中的Map屬性的大小: <s:property value="map.size"/><br/>   
  18. <hr/>  
  19. 訪問ActionContext中的普通屬性:<s:property value="#inte"/><br/>  
  20. 訪問ActionContext中的對象屬性:<s:property value="#user2.loginname"/><br/>  
  21. <hr/>  
  22. 訪問Action中的普通方法:<s:property value="getAppName()"/><br/>  
  23. 訪問ActionContext中的某個對象上的普通方法:<s:property value="#user2.info()"/><br/>  
  24. <hr/>  
  25. 訪問靜態屬性:<s:property value="@java.lang.Math@PI"/><br/>  
  26. 訪問靜態方法:<s:property value="@java.lang.Math@floor(44.56)"/><br/>  
  27. 訪問Math類中的靜態方法:<s:property value="@@floor(44.56)"/><br/>  
  28. <hr/>  
  29. 調用java.util.Date的構造方法:<s:date name="new java.util.Date()" format="yyyy-MM-dd HH:mm:ss"/><br/>  
  30. 調用java.util.Date的構造方法創建對象,再調用它的方法:<s:property value="new java.util.Date().getTime()"/><br/>  
  31. <hr/>  
  32. 投影查詢:獲取userList中所有loginname的列表:<s:property value="userList.{loginname}"/><br/>  
  33. 選擇查詢:獲取userList中所有score大於60的loginname列表:<s:property value="userList.{?#this.score>60.0}.{loginname}"/><br/>  
  34. 選擇查詢:獲取userList中所有score大於60並且gender爲true的loginname列表:<s:property value="userList.{?(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>  
  35. 選擇查詢:獲取userList中所有score大於60並且gender爲true的第一個元素的loginname:<s:property value="userList.{^(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>  
  36. 選擇查詢:獲取userList中所有score大於60並且gender爲true的最後一個元素的loginname:<s:property value="userList.{$(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>  
  37. <hr/>  
  38. 訪問名爲xxx的請求參數對應的第一個值:<s:property value="#parameters.xxx[0]"/><br/>  
  39. 訪問通過ActionContext中放入Request中的屬性:<s:property value="#request.reqAtt"/><br/>  
  40. 訪問通過ServletActionContext中放入Request中的屬性:<s:property value="#request.reqAtt2"/><br/>  
  41.   
  42. 訪問通過ActionContext中放入Session中的屬性:<s:property value="#session.sesAtt"/><br/>  
  43. 訪問通過ServletActionContext中放入Session中的屬性:<s:property value="#session.sesAtt2"/><br/>  
  44. 訪問通過ActionContext中放入ServletContext中的屬性:<s:property value="#application.appAtt"/><br/>  
  45. 訪問通過ServletActionContext中放入ServletContext中的屬性:<s:property value="#application.appAtt2"/><br/>  
  46.   
  47. 直接訪問屬性域中指定名稱的屬性對應的值:<s:property value="#attr.sesAtt2"/><br/>  
  48. <br/><br/><hr/>  
  49. <s:iterator value="userList" status="vs">  
  50.     <s:if test="%{#vs.odd}">  
  51.         <span style="color: red">  
  52.             <s:property value="#vs.count"/>: <s:property value="loginname"/>,<s:date name="birthday" format="yyyy-MM-dd HH:mm:ss"/><br/>  
  53.         </span>  
  54.     </s:if>  
  55.     <s:else>  
  56.         <span style="color: blue">  
  57.             <s:property value="#vs.count"/>: <s:property value="loginname"/>,<s:date name="birthday" format="yyyy-MM-dd HH:mm:ss"/><br/>  
  58.         </span>  
  59.     </s:else>  
  60. </s:iterator>  
  61.   
  62. <hr/><s:debug/>  
  63.   </body>  
  64. </html></span></span>  

 

總結:

在上邊大家都好奇爲什麼都用struts的S標籤,因爲OGNL是通常要結合Struts 2的標誌一起使用,如<s:property value="xx" />


 Action類與JSP頁面之間的數據傳遞

 1) 通過HttpServletRequest,HttpSession,ServletContext來傳遞數據。

    a) Action中傳數據:在Action類的請求處理方法中先獲取各個作用域對象

    ServletActionContext.getRequest();

    ServletActionContext.getRequest().getSession();

    ServletActionContext.getServletContext();

          然後調用相應的setAttribute(String "鍵", Object 值);

    b) 在JSP頁面中取數據:可以使用EL表達式或代碼片段來取出對應作用域中屬性值。

    c) 頁面中的請求參數傳遞到Action中時,Action中直接定義對應名稱的屬性,並提供setter方法即可封裝此數據。

    

 2) 通過ActionContext實例來傳遞數據。 ActionContext針對每個正在執行Action的線程中綁定一份。

   a) Action中通過ActionContext傳遞數據。

      ActionContext提供了put(String "鍵", Object 值);  //數據不會映射到HttpServletRequest中。

      ActionContext提供的getSession().put(String "鍵", Object 值);  //數據會自動映射到HttpSession中。

      ActionContext提供的getApplication().put(String "鍵", Object 值); //數據會自動映射到ServletContext中。

   b) 在JSP頁面取數據:struts2推薦使用OGNL來取ActionContext中的數據。



1. Struts2中的OGNL的使用。


2. OGNL:對象圖導航語言。通過OGNL表達式可以獲取對象的屬性,調用對象的方法,或構造出對象。

  1) OGNL上下文中有一個根對象。這個根對象可以直接獲取。不需要#。

  2)支持常量:

         字符串常量、字符常量、

         數值常量:int、long、float、double

         布爾常量:true、false

    Null常量 : null

         支持操作符:支持Java的所有操作符,還支持特有的操作符: ,、 {}、in、not in;


 Struts2中的OGNL:

  1) Struts2將ActionContext設置爲OGNL上下文,並將值棧(ValueStack)作爲OGNL的根對象放置到ActionContext中。

  2) Struts2總是把當前Action實例放置在值棧的棧頂。所以,在OGNL中引用Action中的屬性也可以省略“#”。

  

 常用標籤

 1) <s:property value="OGNL"/>

 2) <s:date name="OGNL" format=""/>

 3) <s:if test="OGNL"></s:if><s:elseif test="OGNL"></s:elseif><s:else></s:else>

★4) <s:iterator value="OGNL" status="vs">...</s:iterator>

 5) <s:debug/>

 


struts2中#、%和$這三個符號的使用方法【摘自max struts2教程】 

 

一、"#"的用法 

   1、 訪問OGNL上下文和Action上下文,#相當於ActionContext.getContext();下表有幾個ActionContext中有用的屬性: 

        parameters 包含當前HTTP請求參數的Map #parameters.id[0]作用相當於request.getParameter("id") 

       request 包含當前HttpServletRequest的屬性(attribute)的Map #request.userName相當於request.getAttribute("userName")

       session 包含當前HttpSession的屬性(attribute)的Map #session.userName相當於session.getAttribute("userName") 

       application 包含當前應用的ServletContext的屬性(attribute)的Map #application.userName相當於application.getAttribute("userName") 

       attr 用於按request > session > application順序訪問其屬性(attribute) #attr.userName相當於按順序在以上三個範圍(scope)內讀取userName屬性,直到找到爲止 

     2、用於過濾和投影(projecting)集合,如books.{?#this.price<100}; 

     3、構造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。 


二、"%"的用法 

    “%”符號的用途是在標誌的屬性爲字符串類型時,計算OGNL表達式的值。例如在Ognl.jsp中加入以下代碼: 

    <h3>%的用途</h3> 

    <p><s:url value="#foobar['foo1']" /></p> 

    <p><s:url value="%{#foobar['foo1']}" /></p> 


三、"$"的用法 

    1、用於在國際化資源文件中,引用OGNL表達式 

    2、在Struts 2配置文件中,引用OGNL表達式 

     例如: 

         <action name="AddPhoto" class="addPhoto"> 

            <interceptor-ref name="fileUploadStack" />            

            <result type="redirect">ListPhotos.action?       albumId=${albumId}</result> 

        </action>

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