日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Struts2中的OGNL表达式

發(fā)布時間:2023/12/4 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Struts2中的OGNL表达式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
基礎(chǔ)知識(三) Struts2中的OGNL表達式
淺析值棧

ValueStack對象相當(dāng)于一個棧,它貫穿整個Action的生命周期,每個Action類的對象實例都會擁有一個ValueStack對象
當(dāng)Struts2接收到一個*.action請求后,并不是直接調(diào)用Action方法,而是先將Action類的相應(yīng)屬性放到ValueStack對象的頂層節(jié)點
值棧也位于內(nèi)存中,它也是和parameters、request、session、application、attr對象放在一起的
值棧屬于ONGL Context里面的根對象。也就是說它位于整個內(nèi)存中最最重要的地方,所以叫根對象
根對象和另外五個對象是有區(qū)別的,根對象可以省寫#號,比如<s:property value="user.username"/>
值棧的生命周期與request請求相關(guān),每次請求產(chǎn)生一個值棧。默認所有的Action會被自動放到值棧里


服務(wù)器跳轉(zhuǎn)時共用值棧
假設(shè)從一個Action11通過服務(wù)器跳轉(zhuǎn)到Action22的話,就意味著這兩個Action是共享一個值棧的,因為一次請求只使用一個值棧
這時內(nèi)存中情況是這樣的:首先接收到Action11請求后,會產(chǎn)生一個值棧,在棧頂存放Action11對象以及它所有的屬性
然后經(jīng)過服務(wù)器跳轉(zhuǎn)到Action22,這時就會把Action22對象壓入值棧的棧頂位置,此時Action11對象以及它的所有屬性就位于棧底了


取值過程
棧的特征是后進先出。于是首先到棧頂?shù)膶ο罄锊檎沂欠翊嬖谶@個屬性,如果棧頂?shù)腁ction22對象中不存在這個屬性的話
它就會繼續(xù)向下尋找直至棧底對象,一直查找是否存在這個屬性
如果最后找到該屬性的話,那么就會在JSP頁面中通過<s:property value="username"/>輸出屬性值
如果在Action22和Action11都有一個同名的同類型的username屬性的話,那么將輸出Action22中的屬性值
因為它是先從棧頂開始尋找屬性的,值棧的特征就是后進先出,但有個前提:請求過程是通過服務(wù)器跳轉(zhuǎn)的


三個語法
假設(shè)此時想要獲取Action11中的username屬性的話,就可以使用值棧的Top語法或者N語法
使用Top語法獲取值棧中的第二個對象的屬性:<s:property value="[1].top.username"/>
使用 N 語法獲取值棧中的第二個對象的屬性:<s:property value="[1].username"/>
另外值棧還有一個@語法,例如使用@語法調(diào)用Action中的靜態(tài)方法:<s:property value="@vs@getVOMethod()"/>
@vs@get()等價于@vs1@getVOMethod(),指的是棧頂對象的靜態(tài)getVOMethod()方法
同理@vs2@getVOMethod()就是取值棧中第二個對象的靜態(tài)getVOMethod()方法


客戶端跳轉(zhuǎn)時使用各自的值棧
假如中間某一個步驟中出現(xiàn)了客戶端跳轉(zhuǎn)的話,那么兩個Action所使用的就是兩個不同的值棧了
所以在Action22中就不能再使用Action11中的屬性了,在最后跳轉(zhuǎn)到的JSP頁面中也就無法獲取Action11的屬性了
也即從Action22跳轉(zhuǎn)到JSP頁面時使用的是redirect的話,那么最后值棧中是沒有任何的Action對象的
這個時候我們可以通過鏈接傳參,比如<result type="redirect">test.jsp?netname=${username}</result>
意思就是取出Action22中的username屬性作為參數(shù),通過瀏覽器地址欄傳遞到JSP頁面中
然后使用OGNL中的#號獲取Paraments對象的屬性,即<s:property value="#parameters.netname"/>就可以取到值了
輔助參考:http://blog.csdn.net/jadyer/archive/2010/09/16/5887509.aspx


手工向值棧中壓入對象
正常情況下值棧保存的是Action對象,而我們也可以直接往值棧中添加其它對象,這時可以在Action中添加如下代碼
向值棧中添加對象:ActionContext.getContext.getValueStack().push(new Student("沈浪",22));
而且我們手工往值棧中添加的Student對象會位于棧頂。這是因為Struts2會首先初始化Action,然后才能調(diào)用它的方法
初始化Action的時候,便把Action放到值棧中了,然后在執(zhí)行它的execute()方法時,就又往值棧中添加了Student對象


淺析OGNL
OGNL是Object-Graph Navigation Language的縮寫,是一種功能強大的表達式語言
通過它簡單一致的表達式語法,可以存取對象的任意屬性,調(diào)用對象的方法,遍歷整個對象的結(jié)構(gòu)圖,實現(xiàn)字段類型轉(zhuǎn)化等功能
OGNL用得最多的地方就是和Struts2的標(biāo)簽綁定,也可以在配置文件中通過${}使用OGNL表達式


OGNL中$號的使用
1..在國際化資源文件中,引用OGNL表達式
2..在struts.xml文件中,引用OGNL表達式


OGNL中%號的使用
1..使用%{}可以取出保存在值堆棧中的Action對象,直接調(diào)用它的方法
2..如果Action繼承了ActionSupport,那么在頁面標(biāo)簽中可以使用%{getText('key')}獲取國際化信息
輔助參考:http://blog.csdn.net/jadyer/archive/2010/09/16/5887545.aspx

OGNL中#號的使用
OGNL中的#號可以取出堆棧上下文中存放的對象

名稱 作用 例子
attr 用于按request>>session>>application順序訪問其屬性 #attr.userName相當(dāng)于按順序從三個范圍讀取userName屬性直到找到為止
request 包含當(dāng)前HttpServletRequest的屬性的Map #request.userName相當(dāng)于request.getAttribute("userName")
session 包含當(dāng)前HttpSession的屬性的Map #session.userName相當(dāng)于session.getAttribute("userName")
application 包含當(dāng)前應(yīng)用的ServletContext的屬性的Map #application.userName相當(dāng)于application.getAttribute("userName")
parameters 包含當(dāng)前HTTP請求參數(shù)的Map #parameters.id[0]相當(dāng)于request.getParameter("id")


獲取Action中的屬性值或者Action中的對象的某某屬性值
利用<s:property/>標(biāo)簽可以直接獲取Action中的引用類型user里面的username屬性
同樣可以通過user.address.addr獲取user中引用類型address中的addr屬性的值
像這種一層一層往下傳遞的訪問方式,即所謂的導(dǎo)航,也就是一步步的往下調(diào)用

調(diào)用Action的對象里面的普通方法
默認的會把Action放到值棧里面,而值棧在訪問的時候,并不需要值棧的名字
當(dāng)我們調(diào)用<s:property value="user.getVOMethod()"/>的時候
它會自動到值棧里面查找Action對象里面有沒有user對象,然后它就發(fā)現(xiàn)有user
然后它就再找user里面有沒有g(shù)etVOMethod()方法,然后它發(fā)現(xiàn)有,于是調(diào)用getVOMethod()
實際上調(diào)用User中的getVOMethod()方法的過程與獲取表單中的姓名密碼的方式都是相同的
都是到值棧里面查找,找是否存在user對象,如果存在,接著查找user中是否存在某某屬性或方法

調(diào)用Action中的靜態(tài)方法
同樣我們也可以在JSP頁面中寫一個OGNL表達式調(diào)用Action中的靜態(tài)方法
調(diào)用Action中的靜態(tài)方法時,與調(diào)用user對象的getVOMethod()方法的過程,是截然不同的
此時value的寫法是固定的,以@開頭,后面跟上具體的包名,然后@加上靜態(tài)方法
比如<s:property value="@com.jadyer.action.LoginAction@getStatic()"/>
另外user對象是LoginAction中的一個屬性,這個屬性會自動的放到值棧里面
而值棧調(diào)用的時候,不用加上@或者包名等等,所以直接user.getVOMethod()就可以了

調(diào)用JDK類中的靜態(tài)方法
可以使用<s:property value="@@floor(46.58)"/>輸出floor()的執(zhí)行結(jié)果
這就意味著如果不在@@中指定類的話,默認的就表示java.lang.Math類
當(dāng)前大多數(shù)情況下,我們都不會省略這個類,都會寫全了的,然后在后面加上靜態(tài)方法

集合的偽屬性
OGNL能夠引用集合的一些特殊的屬性,這些屬性并不是JavaBean模式,例如size()、length()
當(dāng)表達式引用這些屬性時,OGNL會調(diào)用相應(yīng)的方法,這就是偽屬性
比如獲取List的大小:<s:property value="testList.size"/>
??????List的偽屬性:size、isEmpty、iterator
???????Set的偽屬性:size、isEmpty、iterator
???????Map的偽屬性:size、isEmpty、keys、values
??Iterator的偽屬性:next、hasNext
Enumeration偽屬性:next、hasNext、nextElement、hasMoreElements

獲取集合中元素的實質(zhì)就是調(diào)用它的toString()方法
它還可以直接獲取集合中的元素,事實上是在調(diào)用集合的toString()方法
所以我們可以根據(jù)實際情況通過重寫集合的toString()方法來實現(xiàn)個性? 化輸出
甚至它還可以像訪問數(shù)組那樣,直接testList[2]獲取集合中的元素
但這種方法只適用于List,不適用于Map。因為Map的索引是key,不是數(shù)值
另外,由于HashSet中的元素是沒有順序的,所以也不能用下標(biāo)獲取單個元素

Lambda表達式
補充一下:使用Lambda表達式可以在OGNL中書寫遞歸式子,在幫助中對它有很詳細的說明
打開幫助中的//struts-2.0.14-all//struts-2.0.14//docs//index.html頁面
在左側(cè)的Documentation下面點擊Guides鏈接,然后在這個頁面中點擊OGNL
最后跳轉(zhuǎn)到//struts-2.0.14-all//struts-2.0.14//docs//docs//ognl.html
將這個頁面右側(cè)的下拉條拖放到最下面,就會看到它的說明了,它舉的例子如下所示
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
Lambda表達式的語法是:[...]?,中括號前面有一個冒號,所有東西都在中括號里面寫
也就是說我們只要看到一個冒號跟著一個中括號,就表示這里使用的是Lambda表達式
#this指的是表達式的參數(shù)
所以這個例子可以這樣理解:先判斷這個參數(shù)是否等于零,如果等于零,那么它的值最后就是零
如果參數(shù)不等于零,就再判斷它是否等于壹。如果參數(shù)等于壹,那么它的值最后就是壹
如果參數(shù)不等于壹,就繼續(xù)調(diào)用#fib。注意這里已經(jīng)用中括號將整體的值賦給了fib
實際上很少能夠用得到Lambda表達式

利用投影獲取屬性
利用投影獲取List中對象的username屬性時,其中{}表示的是一個集合
stus.{username}就表示將suts中所有的username屬性取出組成一個新的列表

利用選擇獲取屬性
OGNL表達式是很靈活的,可以同時使用選擇技術(shù)與投影技術(shù)獲取屬性
使用選擇技術(shù)時,#this代表當(dāng)前元素,問號?是把所有滿足條件的元素都取出來
上箭頭^是開始的意思,所以stus.{^#this.grade>=60}.{username}輸出的是[張三]
注意,此時輸出文本中包含中括號,這表示它是一個列表
而stus.{?#this.grade>=60}.{username}[0]輸出的是張三,是字符串,二者是不同的
美元符號$是結(jié)束的意思,所以stus.{$#this.grade>=60}.{username}輸出的是[王五]
這三個符合:問號、上箭頭、美元符所返回的都是List

補充
1..當(dāng)OGNL取不到值的時候,它不會報錯,而是什么都不顯示
2..<s:property value="[0]"/>返回的是ValueStack中從上至下的所有的Object
????<s:property value="[1]"/>返回的是ValueStack中從上至下的第二個Object
3..<s:property value="[0].username"/>返回的是成員變量username的值
??? 假設(shè)ValueStack中存在兩個Action的話,如果第一個Action如果沒有username變量
??? 那么它會繼續(xù)找第二個Action。那么在什么情況下ValueStack中會存在兩個Action呢
??? 答案是在struts.xml中配置的是從一個Action通過<result type="chain">跳轉(zhuǎn)到另一個Action
4..<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
??? 在Struts2.1.6中必須設(shè)置struts.ognl.allowStaticMethodAccess為true之后
??? 才允許使用OGNL訪問靜態(tài)方法。而在Struts2.0.11則無需設(shè)置,即可直接訪問


下面是OGNL測試的工程代碼,這是一個Struts2.0.11應(yīng)用

首先是web.xml文件

[xhtml]?view plaincopy
  • <?xmlversion="1.0"encoding="UTF-8"?>?
  • <web-app?version="2.5"??
  • ????xmlns="http://java.sun.com/xml/ns/javaee"??
  • ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
  • ????xsi:schemaLocation="http://java.sun.com/xml/ns/javaee??;
  • ????http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">?
  • ????<filter>?
  • ????????<filter-name>struts2</filter-name>?
  • ????????<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>?
  • ????</filter>?
  • ????<filter-mapping>?
  • ????????<filter-name>struts2</filter-name>?
  • ????????<url-pattern>/*</url-pattern>?
  • ????</filter-mapping>?
  • ????<welcome-file-list>?
  • ????????<welcome-file>login.jsp</welcome-file>?
  • ????</welcome-file-list>???
  • </web-app>?
  • [xhtml]?view plaincopy
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <web-app?version="2.5"???
  • ????xmlns="http://java.sun.com/xml/ns/javaee"???
  • ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"???
  • ????xsi:schemaLocation="http://java.sun.com/xml/ns/javaee???;
  • ????http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">??
  • ????<filter>??
  • ????????<filter-name>struts2</filter-name>??
  • ????????<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>??
  • ????</filter>??
  • ????<filter-mapping>??
  • ????????<filter-name>struts2</filter-name>??
  • ????????<url-pattern>/*</url-pattern>??
  • ????</filter-mapping>??
  • ????<welcome-file-list>??
  • ????????<welcome-file>login.jsp</welcome-file>??
  • ????</welcome-file-list>????
  • </web-app>??
  • 然后是用于輸入用戶名和密碼等信息的測試頁面login.jsp

    ?

    [xhtml]?view plaincopy
  • <%@ page?language="java"pageEncoding="UTF-8"%>?
  • <h1>這是測試OGNL使用的登錄頁面</h1>?
  • <h3><fontcolor="red">提示:</font>程序設(shè)定的用戶名和密碼各為<fontcolor="blue"><strong>admin</strong></font>和<fontcolor="blue"><strong>jadyer</strong></font></h3>?
  • <h3><fontcolor="red">注意:</font>用戶名和密碼不正確時將停留在頁面不動</h3>?
  • <formaction="<%=request.getContextPath()%>/login.action"method="POST">?
  • ????<%--這里user.username匹配的是LoginAction中的引用類型user里面的username屬性--%>?
  • ????<%--查看標(biāo)簽庫說明的話,就知道name中指定的是對象。這里它不是字符串,而是OGNL表達式--%>?
  • ??? 姓名:<inputtype="text"name="user.username"><br>?
  • ??? 密碼:<inputtype="text"name="user.password"><br>?
  • ??? 地址:<inputtype="text"name="user.address.addr"><br>?
  • ????<inputtype="submit"value="測試OGNL的輸出">?
  • </form>?
  • [xhtml]?view plaincopy
  • <%@?page?language="java"?pageEncoding="UTF-8"%>??
  • <h1>這是測試OGNL使用的登錄頁面</h1>??
  • <h3><font?color="red">提示:</font>程序設(shè)定的用戶名和密碼各為<font?color="blue"><strong>admin</strong></font>和<font?color="blue"><strong>jadyer</strong></font></h3>??
  • <h3><font?color="red">注意:</font>用戶名和密碼不正確時將停留在頁面不動</h3>??
  • <form?action="<%=request.getContextPath()%>/login.action"?method="POST">??
  • ????<%--這里user.username匹配的是LoginAction中的引用類型user里面的username屬性--%>??
  • ????<%--查看標(biāo)簽庫說明的話,就知道name中指定的是對象。這里它不是字符串,而是OGNL表達式--%>??
  • ????姓名:<input?type="text"?name="user.username"><br>??
  • ????密碼:<input?type="text"?name="user.password"><br>??
  • ????地址:<input?type="text"?name="user.address.addr"><br>??
  • ????<input?type="submit"?value="測試OGNL的輸出">??
  • </form>??
  • 然后是用于顯示OGNL處理結(jié)果的loginSuc.jsp頁面

    ?

    [xhtml]?view plaincopy
  • <%@ page?language="java"pageEncoding="UTF-8"%>?
  • <%@ taglib?prefix="s"uri="/struts-tags"%>?
  • <h1>這是使用OGNL輸出的結(jié)果頁面</h1>?
  • <table?border="9">?
  • ????<tr>?
  • ????????<tdalign="right">獲取姓名屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="user.username"/></td>?
  • ????????<%-- 另外還有兩種寫法也是可以正常輸出值棧中對象的普通屬性的 --%>?
  • ????????<%--?<s:propertyvalue="user['username']"/>?--%>?
  • ????????<%--?<s:propertyvalue="user[/"username/"]"/>?--%>?
  • ????????<%-- 但是如果寫成下面這種形式的話,就什么都不會輸出了 --%>?
  • ????????<%--?<s:propertyvalue="user[username]"/>?--%>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取地址屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="user.address.addr"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">調(diào)用值棧中的對象的普通方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="user.getVOMethod()"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">調(diào)用值棧中Action的普通方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="getCommon()"/></td>?
  • ????</tr>?
  • </table>?
  • <hr/>?
  • <table?border="9">?
  • ????<tr>?
  • ????????<tdalign="right">獲取普通類的靜態(tài)屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="@com.jadyer.vo.Address@TIPS"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">訪問普通類的構(gòu)造方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="new com.jadyer.vo.Student('張小三',22).username"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">調(diào)用Action中的靜態(tài)方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="@com.jadyer.action.LoginAction@getStatic()"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">調(diào)用JDK中的類的靜態(tài)方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="@java.util.Calendar@getInstance().time"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">調(diào)用JDK中的類的靜態(tài)方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="@java.lang.Math@floor(46.58)"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">調(diào)用JDK中的類的靜態(tài)方法:</td>?
  • ????????<tdalign="left"><s:propertyvalue="@@floor(46.58)"/></td>?
  • ????</tr>?
  • </table>?
  • <hr/>?
  • <tableborder="9">?
  • ????<tr>?
  • ????????<tdalign="right">獲取List中的所有元素:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testList"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Set中的所有元素:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testSet"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Map中的所有元素:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testMap"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Map中的某個元素:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testMap['m22']"/></td>?
  • ????????<%-- 另外還有兩種寫法也是可以正常獲取Map中的某個具體元素的 --%>?
  • ????????<%--?<s:propertyvalue="testMap.m22"/>?--%>?
  • ????????<%--?<s:propertyvalue="testMap[/"m22/"]"/>?--%>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Set中的某個元素:</td>?
  • ????????<%-- 由于Set中的元素是無順序的,所以不能使用下標(biāo)獲取數(shù)據(jù),所以這里什么也得不到 --%>?
  • ????????<tdalign="left"><s:propertyvalue="testSet[2]"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取List中的某個元素:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testList[2]"/></td>?
  • ????</tr>?
  • </table>?
  • <hr/>?
  • <table?border="9">?
  • ????<tr>?
  • ????????<tdalign="right">獲取List的大小:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testList.size"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Set的大小:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testSet.size"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Map的大小:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testMap.size"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Map中所有的鍵:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testMap.keys"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">獲取Map中所有的值:</td>?
  • ????????<tdalign="left"><s:propertyvalue="testMap.values"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">Lambda計算4的階乘:</td>?
  • ????????<tdalign="left"><s:propertyvalue="#f= :[#this==1?1 : #this*#f(#this-1)],#f(4)"/></td>?
  • ????</tr>?
  • </table>?
  • <hr/>?
  • <tableborder="9">?
  • ????<tr>?
  • ????????<tdalign="right">獲取List中的所有對象:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用投影獲取List中對象的名字:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{username}"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用投影獲取List中第二個對象的名字:</td>?
  • ????????<%-- 使用<s:propertyvalue="stus[1].{username}"/>獲取到的值為:[李四] --%>?
  • ????????<%-- 二者的區(qū)別在于:后者比前者多了一個中括號 --%>?
  • ????????<tdalign="left">?
  • ????????????<s:propertyvalue="stus.{username}[1]"/>???????
  • ????????????<s:propertyvalue="stus[1].{username}"/>?
  • ????????</td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的所有對象:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{?#this.grade>=60}"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的第一個對象:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{^#this.grade>=60}"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的最后一個對象:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{$#this.grade>=60}"/></td>?
  • ????</tr>?
  • </table>?
  • <hr/>?
  • <tableborder="9">?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的所有對象的名字:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{?#this.grade>=60}.{username}"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的第二個對象的名字:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{?#this.grade>=60}.{username}[1]"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的第一個對象的名字:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{^#this.grade>=60}.{username}"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的最后一個對象的名字:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{$#this.grade>=60}.{username}"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用選擇獲取List中成績及格的第一個對象然后求大小:</td>?
  • ????????<tdalign="left"><s:propertyvalue="stus.{^#this.grade>=60}.{username}.size"/></td>?
  • ????</tr>?
  • </table>?
  • <hr/>?
  • <table?border="9">?
  • ????<tr>?
  • ????????<tdalign="right">利用OGNL中的#號獲取attr中的屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="#attr.BB"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用OGNL中的#號獲取request范圍中的屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="#request.req"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用OGNL中的#號獲取session范圍中的屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="#session.ses"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">利用OGNL中的#號獲取Paraments對象的屬性:</td>?
  • ????????<tdalign="left"><s:propertyvalue="#parameters.netname"/></td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">使用&#60;&#37;=request.getParameter&#40;""&#41;&#37;&#62;或者&#36;&#123;param.name&#125;獲取鏈接參數(shù)值:</td>?
  • ????????<tdalign="left">?
  • ??????????? ${param.netname}???????
  • ????????????<%=request.getParameter("netname")%>?
  • ????????</td>?
  • ????</tr>?
  • ????<tr>?
  • ????????<tdalign="right">查看值棧中的信息:</td>?
  • ????????<tdalign="left"><s:debug/></td>?
  • ????</tr>?
  • </table>?
  • [xhtml]?view plaincopy
  • <%@?page?language="java"?pageEncoding="UTF-8"%>??
  • <%@?taglib?prefix="s"?uri="/struts-tags"%>??
  • <h1>這是使用OGNL輸出的結(jié)果頁面</h1>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">獲取姓名屬性:</td>??
  • ????????<td?align="left"><s:property?value="user.username"/></td>??
  • ????????<%--?另外還有兩種寫法也是可以正常輸出值棧中對象的普通屬性的?--%>??
  • ????????<%--?<s:property?value="user['username']"/>?--%>??
  • ????????<%--?<s:property?value="user[/"username/"]"/>?--%>??
  • ????????<%--?但是如果寫成下面這種形式的話,就什么都不會輸出了?--%>??
  • ????????<%--?<s:property?value="user[username]"/>?--%>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取地址屬性:</td>??
  • ????????<td?align="left"><s:property?value="user.address.addr"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">調(diào)用值棧中的對象的普通方法:</td>??
  • ????????<td?align="left"><s:property?value="user.getVOMethod()"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">調(diào)用值棧中Action的普通方法:</td>??
  • ????????<td?align="left"><s:property?value="getCommon()"/></td>??
  • ????</tr>??
  • </table>??
  • <hr/>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">獲取普通類的靜態(tài)屬性:</td>??
  • ????????<td?align="left"><s:property?value="@com.jadyer.vo.Address@TIPS"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">訪問普通類的構(gòu)造方法:</td>??
  • ????????<td?align="left"><s:property?value="new?com.jadyer.vo.Student('張小三',22).username"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">調(diào)用Action中的靜態(tài)方法:</td>??
  • ????????<td?align="left"><s:property?value="@com.jadyer.action.LoginAction@getStatic()"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">調(diào)用JDK中的類的靜態(tài)方法:</td>??
  • ????????<td?align="left"><s:property?value="@java.util.Calendar@getInstance().time"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">調(diào)用JDK中的類的靜態(tài)方法:</td>??
  • ????????<td?align="left"><s:property?value="@java.lang.Math@floor(46.58)"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">調(diào)用JDK中的類的靜態(tài)方法:</td>??
  • ????????<td?align="left"><s:property?value="@@floor(46.58)"/></td>??
  • ????</tr>??
  • </table>??
  • <hr/>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">獲取List中的所有元素:</td>??
  • ????????<td?align="left"><s:property?value="testList"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Set中的所有元素:</td>??
  • ????????<td?align="left"><s:property?value="testSet"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Map中的所有元素:</td>??
  • ????????<td?align="left"><s:property?value="testMap"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Map中的某個元素:</td>??
  • ????????<td?align="left"><s:property?value="testMap['m22']"/></td>??
  • ????????<%--?另外還有兩種寫法也是可以正常獲取Map中的某個具體元素的?--%>??
  • ????????<%--?<s:property?value="testMap.m22"/>?--%>??
  • ????????<%--?<s:property?value="testMap[/"m22/"]"/>?--%>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Set中的某個元素:</td>??
  • ????????<%--?由于Set中的元素是無順序的,所以不能使用下標(biāo)獲取數(shù)據(jù),所以這里什么也得不到?--%>??
  • ????????<td?align="left"><s:property?value="testSet[2]"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取List中的某個元素:</td>??
  • ????????<td?align="left"><s:property?value="testList[2]"/></td>??
  • ????</tr>??
  • </table>??
  • <hr/>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">獲取List的大小:</td>??
  • ????????<td?align="left"><s:property?value="testList.size"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Set的大小:</td>??
  • ????????<td?align="left"><s:property?value="testSet.size"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Map的大小:</td>??
  • ????????<td?align="left"><s:property?value="testMap.size"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Map中所有的鍵:</td>??
  • ????????<td?align="left"><s:property?value="testMap.keys"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">獲取Map中所有的值:</td>??
  • ????????<td?align="left"><s:property?value="testMap.values"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">Lambda計算4的階乘:</td>??
  • ????????<td?align="left"><s:property?value="#f=?:[#this==1?1?:?#this*#f(#this-1)],#f(4)"/></td>??
  • ????</tr>??
  • </table>??
  • <hr/>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">獲取List中的所有對象:</td>??
  • ????????<td?align="left"><s:property?value="stus"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用投影獲取List中對象的名字:</td>??
  • ????????<td?align="left"><s:property?value="stus.{username}"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用投影獲取List中第二個對象的名字:</td>??
  • ????????<%--?使用<s:property?value="stus[1].{username}"/>獲取到的值為:[李四]?--%>??
  • ????????<%--?二者的區(qū)別在于:后者比前者多了一個中括號?--%>??
  • ????????<td?align="left">??
  • ????????????<s:property?value="stus.{username}[1]"/>????????
  • ????????????<s:property?value="stus[1].{username}"/>??
  • ????????</td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的所有對象:</td>??
  • ????????<td?align="left"><s:property?value="stus.{?#this.grade>=60}"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的第一個對象:</td>??
  • ????????<td?align="left"><s:property?value="stus.{^#this.grade>=60}"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的最后一個對象:</td>??
  • ????????<td?align="left"><s:property?value="stus.{$#this.grade>=60}"/></td>??
  • ????</tr>??
  • </table>??
  • <hr/>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的所有對象的名字:</td>??
  • ????????<td?align="left"><s:property?value="stus.{?#this.grade>=60}.{username}"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的第二個對象的名字:</td>??
  • ????????<td?align="left"><s:property?value="stus.{?#this.grade>=60}.{username}[1]"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的第一個對象的名字:</td>??
  • ????????<td?align="left"><s:property?value="stus.{^#this.grade>=60}.{username}"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的最后一個對象的名字:</td>??
  • ????????<td?align="left"><s:property?value="stus.{$#this.grade>=60}.{username}"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用選擇獲取List中成績及格的第一個對象然后求大小:</td>??
  • ????????<td?align="left"><s:property?value="stus.{^#this.grade>=60}.{username}.size"/></td>??
  • ????</tr>??
  • </table>??
  • <hr/>??
  • <table?border="9">??
  • ????<tr>??
  • ????????<td?align="right">利用OGNL中的#號獲取attr中的屬性:</td>??
  • ????????<td?align="left"><s:property?value="#attr.BB"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用OGNL中的#號獲取request范圍中的屬性:</td>??
  • ????????<td?align="left"><s:property?value="#request.req"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用OGNL中的#號獲取session范圍中的屬性:</td>??
  • ????????<td?align="left"><s:property?value="#session.ses"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">利用OGNL中的#號獲取Paraments對象的屬性:</td>??
  • ????????<td?align="left"><s:property?value="#parameters.netname"/></td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">使用&#60;&#37;=request.getParameter&#40;""&#41;&#37;&#62;或者&#36;&#123;param.name&#125;獲取鏈接參數(shù)值:</td>??
  • ????????<td?align="left">??
  • ????????????${param.netname}????????
  • ????????????<%=request.getParameter("netname")%>??
  • ????????</td>??
  • ????</tr>??
  • ????<tr>??
  • ????????<td?align="right">查看值棧中的信息:</td>??
  • ????????<td?align="left"><s:debug/></td>??
  • ????</tr>??
  • </table>??
  • 然后是struts.xml文件

    [xhtml]?view plaincopy
  • <?xmlversion="1.0"encoding="UTF-8"?>?
  • <!DOCTYPE struts PUBLIC?
  • ??? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"?
  • ??? "http://struts.apache.org/dtds/struts-2.0.dtd">?
  • <struts>?
  • ????<packagename="ognl"extends="struts-default">?
  • ????????<actionname="login"class="com.jadyer.action.LoginAction">?
  • ????????????<resultname="input">/login.jsp</result>?
  • ????????????<resultname="success">/loginSuc.jsp?netname=hongyu</result>?
  • ??????????? <!--?
  • ????????????<resultname="success"type="redirect">/loginSuc.jsp?netname=hongyu</result>?
  • ????????????<resultname="success"type="redirect">/loginSuc.jsp?netname=${user.username}</result>??
  • ???????????? -->?
  • ????????</action>?
  • ????</package>?
  • </struts>?
  • [xhtml]?view plaincopy
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <!DOCTYPE?struts?PUBLIC??
  • ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
  • ????"http://struts.apache.org/dtds/struts-2.0.dtd">??
  • <struts>??
  • ????<package?name="ognl"?extends="struts-default">??
  • ????????<action?name="login"?class="com.jadyer.action.LoginAction">??
  • ????????????<result?name="input">/login.jsp</result>??
  • ????????????<result?name="success">/loginSuc.jsp?netname=hongyu</result>??
  • ????????????<!--??
  • ????????????<result?name="success"?type="redirect">/loginSuc.jsp?netname=hongyu</result>??
  • ????????????<result?name="success"?type="redirect">/loginSuc.jsp?netname=${user.username}</result>???
  • ?????????????-->??
  • ????????</action>??
  • ????</package>??
  • </struts>??
  • 接著是用到的三個VO類

    ?

    [java]?view plaincopy
  • package?com.jadyer.vo;?
  • publicclass?User {?
  • ????private?String username;?
  • ????private?String password;?
  • ????private?Address address;?
  • ????/* 三個屬性的setter和getter略 */?
  • ????public?String getVOMethod(){?
  • ????????return"這是User類中的一個普通方法";?
  • ??? }?
  • }?
  • ?
  • ?
  • package?com.jadyer.vo;?
  • publicclass?Address {?
  • ????//如果將TIPS設(shè)為private的話,loginSuc.jsp中就無法獲取它的屬性值了?
  • ????//事實上將一個靜態(tài)的final屬性設(shè)為private是毫無意義的?
  • ????//因為既然設(shè)置成了靜態(tài),那么就是供他人調(diào)用的,如果再設(shè)成private的話,別的地方根本就無法調(diào)用了?
  • ????//即使OGNL再怎么強大,它也不可能違反Java的規(guī)則,所以不要將靜態(tài)的屬性設(shè)為私有?
  • ????publicstaticfinal?String TIPS =?"玄玉加油!!";?
  • ????//addr屬性的setter和getter略?
  • ????private?String addr;?
  • }?
  • ?
  • ?
  • package?com.jadyer.vo;?
  • publicclass?Student {?
  • ????private?String username;?
  • ????privateint?grade;?
  • ????/* 兩個屬性的setter和getter略 */?
  • ?????
  • ????//只要是重寫一個類的構(gòu)造方法,就必須要為這個類保留空的構(gòu)造方法?
  • ????//因為框架默認的都會去調(diào)用無參的空的構(gòu)造方法?
  • ????public?Student(){};?
  • ????public?Student(String username,int?grade){?
  • ????????this.username = username;?
  • ????????this.grade = grade;?
  • ??? }?
  • ????@Override?
  • ????public?String toString() {?
  • ????????//如果不重寫它的toString()方法的話,默認調(diào)用toString()將輸出【類型+@+內(nèi)存地址的哈希值】?
  • ????????return"{學(xué)生姓名:"?+ username +",成績:"?+ grade +?"}";?
  • ??? }?
  • }?
  • [java]?view plaincopy
  • package?com.jadyer.vo;??
  • public?class?User?{??
  • ????private?String?username;??
  • ????private?String?password;??
  • ????private?Address?address;??
  • ????/*?三個屬性的setter和getter略?*/??
  • ????public?String?getVOMethod(){??
  • ????????return?"這是User類中的一個普通方法";??
  • ????}??
  • }??
  • ??
  • ??
  • package?com.jadyer.vo;??
  • public?class?Address?{??
  • ????//如果將TIPS設(shè)為private的話,loginSuc.jsp中就無法獲取它的屬性值了??
  • ????//事實上將一個靜態(tài)的final屬性設(shè)為private是毫無意義的??
  • ????//因為既然設(shè)置成了靜態(tài),那么就是供他人調(diào)用的,如果再設(shè)成private的話,別的地方根本就無法調(diào)用了??
  • ????//即使OGNL再怎么強大,它也不可能違反Java的規(guī)則,所以不要將靜態(tài)的屬性設(shè)為私有??
  • ????public?static?final?String?TIPS?=?"玄玉加油!!";??
  • ????//addr屬性的setter和getter略??
  • ????private?String?addr;??
  • }??
  • ??
  • ??
  • package?com.jadyer.vo;??
  • public?class?Student?{??
  • ????private?String?username;??
  • ????private?int?grade;??
  • ????/*?兩個屬性的setter和getter略?*/??
  • ??????
  • ????//只要是重寫一個類的構(gòu)造方法,就必須要為這個類保留空的構(gòu)造方法??
  • ????//因為框架默認的都會去調(diào)用無參的空的構(gòu)造方法??
  • ????public?Student(){};??
  • ????public?Student(String?username,int?grade){??
  • ????????this.username?=?username;??
  • ????????this.grade?=?grade;??
  • ????}??
  • ????@Override??
  • ????public?String?toString()?{??
  • ????????//如果不重寫它的toString()方法的話,默認調(diào)用toString()將輸出【類型+@+內(nèi)存地址的哈希值】??
  • ????????return?"{學(xué)生姓名:"?+?username?+?",成績:"?+?grade?+?"}";??
  • ????}??
  • }??
  • 最后是用來提供OGNL測試的數(shù)據(jù)的LoginAction.java

    [java]?view plaincopyprint?
  • package?com.jadyer.action;?
  • ?
  • import?java.util.ArrayList;?
  • import?java.util.HashMap;?
  • import?java.util.HashSet;?
  • import?java.util.List;?
  • import?java.util.Map;?
  • import?java.util.Set;?
  • ?
  • import?org.apache.struts2.interceptor.RequestAware;?
  • import?org.apache.struts2.interceptor.SessionAware;?
  • ?
  • import?com.jadyer.vo.Student;?
  • import?com.jadyer.vo.User;?
  • import?com.opensymphony.xwork2.ActionSupport;?
  • ?
  • @SuppressWarnings({"serial","unchecked"})?
  • publicclass?LoginActionextends?ActionSupport?implements?RequestAware,SessionAware {?
  • ????private?User user;?
  • ????private?List testList =?new?ArrayList();?
  • ????private?Set testSet =new?HashSet();?
  • ????private?Map testMap =?new?HashMap();?
  • ????private?List stus =?new?ArrayList();?
  • ?????
  • ????/* 以上五個屬性的setter和getter略 */?
  • ?????
  • ????private?Map request;?
  • ????private?Map session;?
  • ????publicvoid?setRequest(Map request) {?
  • ????????this.request = request;?
  • ??? }?
  • ????publicvoid?setSession(Map session) {?
  • ????????this.session = session;?
  • ??? }?
  • ?????
  • ????publicstatic?String getStatic(){?
  • ????????return"這是LoginAction中的一個靜態(tài)方法";?
  • ??? }?
  • ????public?String getCommon(){?
  • ????????return"這是LoginAction中的一個普通方法";?
  • ??? }?
  • ?????
  • ????@Override?
  • ????public?String execute()?throws?Exception {?
  • ????????if(user.getUsername().trim().equalsIgnoreCase("admin") && user.getPassword().equals("jadyer")){?
  • ??????????? testList.add("list11");?
  • ??????????? testList.add("list22");?
  • ??????????? testList.add("list33");?
  • ??????????? testList.add("list44");?
  • ??????????? testList.add("list55");?
  • ?????????????
  • ??????????? testSet.add("set11");?
  • ??????????? testSet.add("set22");?
  • ??????????? testSet.add("set33");?
  • ??????????? testSet.add("set22");?
  • ??????????? testSet.add("set11");?
  • ?????????????
  • ??????????? testMap.put("m11",?"map11");?
  • ??????????? testMap.put("m22","map22");?
  • ??????????? testMap.put("m33",?"map33");?
  • ??????????? testMap.put("m44","map44");?
  • ??????????? testMap.put("m55",?"map55");?
  • ?????????????
  • ??????????? stus.add(new?Student("張三",88));?
  • ??????????? stus.add(new?Student("李四",77));?
  • ??????????? stus.add(new?Student("王五",66));?
  • ??????????? stus.add(new?Student("馬六",55));?
  • ?????????????
  • ??????????? request.put("req","這是通過OGNL中的#號獲取的request屬性范圍的值");?
  • ??????????? session.put("ses",?"這是通過OGNL中的#號獲取的session屬性范圍的值");?
  • ??????????? request.put("BB","這是通過OGNL中的#號獲取的request屬性范圍的BB");?
  • ??????????? session.put("BB",?"這是通過OGNL中的#號獲取的session屬性范圍的BB");?
  • ????????????return?SUCCESS;?
  • ??????? }else{?
  • ????????????return?INPUT;?
  • ??????? }?
  • ??? }????
  • }
  • ?
  • 總結(jié)

    以上是生活随笔為你收集整理的Struts2中的OGNL表达式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。