struts2總結之 OGNL表達式 收藏
最近的項目開(kāi)發(fā)中使用了struts2的框架,但是好多人都不清楚struts2的標簽的具體的用法,要想完全掌握struts2標簽的用法,那么你必須先精通了struts2中OGNL的用法。struts2中很多東西其實(shí)理解就行,但是惟獨OGNL雖然內容不多,但是確必須的精通,這是學(xué)習struts2的基礎。
Struts2 中內置了OGNL表達式的支持,使得Struts2的具有比Struts1更為強大的數據訪(fǎng)問(wèn)的功能。本文主要講解OGNL的使用方法,并不會(huì )去講解一些原理性的東西,想要了解的朋友可以自己去查閱相關(guān)的資料
在OGNL的使用主要分以下部分來(lái)講解:1.使用OGNL訪(fǎng)問(wèn)對象(不同范圍的取值)
2.OGNL的集合操作(OGNL元素符,以及過(guò)濾和投影功能)
3.OGNL訪(fǎng)問(wèn)靜態(tài)成員(怎么訪(fǎng)問(wèn)靜態(tài)成員)
4. lambda表達式,在OGNL中使用一些簡(jiǎn)單的函數以及OGNL總結(在總結之后會(huì )詳解Struts2的標簽的使用)
一、使用OGNL訪(fǎng)問(wèn)對象
1 讀取struts2中的ValueStack中的值
struts2中引入了ValueStack的概念,在struts2中默認使用ValueStack作為OGNL的StackContext的根元素
OGNL在讀取根元素的時(shí)候能夠直接進(jìn)行讀取
假設action中有
private Cat cat; private Dog dog; 倆個(gè)對象,那么在jsp頁(yè)面讀取方法就是
<s:property value="cat.name"/> 讀取Cat的name屬性的值
<s:property value="dog.name"/> 讀取Dog的name屬性值
2 使用#讀取parameters request session application 范圍內的值()
<s:property value="#request.id"/> 相當于 request.getAttribute("id")
<s:property value="#parameters.id"/> 相當于 request.getParameter("id")
<s:property value="#session.id"/> 相當于 session.getAttribute("id")
<s:property value="#application.id"/> 相當于 application.getAttribute("id")
<s:property value="#attr.id"/> 依次搜索PageContext HttpServletRequest HttpSession ServletContext 范圍 ,查找屬性,找到為止
二、OGNL的集合操作
1 創(chuàng )建一個(gè)集合
{e1,e2,e3} 直接創(chuàng )建一個(gè)List類(lèi)型的集合
#{Key1:Value1,Key2:Value2} 構建一個(gè)Map類(lèi)型的集合
使用: <s:set name="sex" value="#{'1':'男','2':'女'}"/>
<s:property value="#sex[id]"/> 在ValueStack范圍內找到id的值, 并用它作為key去查找對應的
value 并顯示出來(lái)
2 OGNL元素符
對于集合,OGNL提供了兩個(gè)元素符:in和not in,其中in判斷某個(gè)元素是否在指定集合中;not in則用于
判斷某個(gè)元素是否不在指定集合中。
判斷一個(gè)對象是否在List內存在:
<s:if test="'foo' in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
<s:if test="'foo' not in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
3 過(guò)濾與投影集合
假設有一個(gè)books的List集合存在于ValueStack中,存放了多個(gè)Book類(lèi)型的對象
我們可以通過(guò)這樣進(jìn)行過(guò)濾取值
<s:iterator value="books.{?#this.price>35}"> 這樣只會(huì )取到價(jià)格大于35的書(shū)籍,很好的起到了過(guò)濾的
作用,
?取出所有符合邏輯的元素
^ 取出符合邏輯的第一個(gè)元素
$ 取出符合邏輯的最后一個(gè)元素
三、OGNL訪(fǎng)問(wèn)靜態(tài)成員
在實(shí)際的開(kāi)發(fā)中像頁(yè)面的參數傳遞是絕對拒絕使用硬編碼的,最好的解決方式有2種:一種是寫(xiě)在國際化配置文件中;另外的一種就是建立一個(gè)類(lèi),專(zhuān)門(mén)維護靜態(tài)成員,所有硬編碼的地方都調用它就可以了。
struts2 中默認提供了一些訪(fǎng)問(wèn)靜態(tài)成員的方式,但是默認是關(guān)閉的,所以應該在struts2的配置文件中先設置
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
設置之后就可以用以下的表達式來(lái)訪(fǎng)問(wèn)靜態(tài)成員了。
1 訪(fǎng)問(wèn)靜態(tài)方法
<s:property value="@com.netsdar.song.manager.util.AppUtil@getName()"/>
2 訪(fǎng)問(wèn)靜態(tài)常量
<s:property value="@com.netsdar.song.manager.util.AppUtil@Index_Title"/>
四、lambda表達式,在OGNL中使用一些簡(jiǎn)單的函數以及OGNL總結
1 lambda表達式
這個(gè)表達式,我其實(shí)也很少去用,這里給大家拿個(gè)例子講解一下吧
<s:property value="#conv =:[#this==1?'男':#this==2?'女':''], #conv(1)" />
這句的作用就是,value="#conv =: 定義一個(gè)函數 conv
[#this==1?'男' 定義 conv(1)=男
#this==2?'女' 定義 conv(2)=女
當然這個(gè)只是一個(gè)簡(jiǎn)單的例子,這里支持復雜的函數運算。對于一些簡(jiǎn)單的邏輯更推薦使用struts2的標簽來(lái)處理。復雜點(diǎn)的不做具體講解,引用別人的一個(gè)例子
例如:
Fibonacci:
if n==0 return 0;
elseif n==1 return 1;
else return fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89
OGNL的Lambda表達式如何工作呢?
Lambda表達式必須放在方括號內部,#this表示表達式的參數。例如:
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)]定義了一個(gè)Lambda表達式,
#fib(11) 調用了這個(gè)表達式。
2 總結
這里主要講解一下使用注意事項
<s:url value="#foobar['foo1']"> 如果你這樣使用標簽 ,那么它絕對不會(huì )是你想要的,它會(huì )按照你的
輸入原樣的輸出的 #foobar['foo1']
正確的使用: <s:url value="%{#foobar['foo1']}"> %{} 用于對括號內用ognl求值
struts2的action,大家都習慣了生成get與set方法,其實(shí)新版的沒(méi)有這倆個(gè)方法也能插值進(jìn)去的,它采用了java的反射機制來(lái)實(shí)現,不過(guò)官方還是建議按照舊的方法用。