程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> struts2中的Ognl

struts2中的Ognl

編輯:關於JSP

OGNL表達式是(Object-Graph Navigation Language)是對象圖形化導航語言。OGNL是一個開源的項目,struts2中默認使用OGNL表達式語言來顯示數據。與serlvet中的el表達式的作用是一樣的。OGNL表達式有下面以下特點:

支持對象方法調用,例如:objName.methodName();支持類靜態的方法調用和值訪問,表達式的格式為 @[類全名(包括包路經)]@[方法名 | 值名]例如:@java.lang.String@format('foo%s','bar')@tutorial.MyConstant@APP_NAME; 支持賦值操作和表達式串聯,例如: price=100, discount=0.8, calculatePrice(),這個表達式會返回80; 訪問OGNL上下文(OGNL context)和ActionContext 操作集合對象 類圖 \
ValueStack

ValueStack是一個接口,在struts2中使用OGNL表達式實際上是使用實現了ValueStack接口的類OgnlValueStack,這個類是OgnlValueStack的基礎。ValueStack貫穿整個action的生命周期。每一個action實例都擁有一個ValueStack對象。其中保存了當前action對象和其他相關對象。 Struts2把ValueStack對象保存中名為struts.valueStack的request域中。

ValueStack內存圖
\
ValueStack的組織結構

\

從圖上可以看出OgnlValueStack和我們有關的內容有兩部分:即OgnlContext和CompoundRoot。所以把這兩部分搞清楚很重要。


總圖
\

<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+y7XD96O6PC9wPgo8cD48L3A+CgrJz828ysdvZ25szerV+7XEyv2+3b3hubnNvKOsv8nS1Mflzvq1w7+0s/bK/b7dtcTX6bPJoaNDb250ZXh01tC1xF9yb290us1WYWx1ZVN0YWNr1tC1xHJvb3QottTP89W7KcDvtcTK/b7dveG5ubrNJiMyMDU0MDvKx9K70fm1xKGj1eK+zdLizrbXxc7Sw8fWu9Do0qqy2df3T2dubENvbnRleHS+zb/J0tTN6rPJttTK/b7dtcS05rrNyKG1xLLZ1/eho1ZhbHVlU3RhY2vE2rK/09DBvbj2wt+8rbXE1+mzybK/t9ajugoKIE9iamVjdFN0YWNrCgpTdHJ1dHO74bDRtq/X97rNz+C52LXEttTP89G5yOu1vU9iamVjdFN0YWNr1tChowpDb250ZXh0TWFwCgpTdHJ1dHO74bDR0rvQqdOzyeS52M+10bnI67W9Q29udGV4dE1hcNbQCgoKPHA+PC9wPgpPR05MIENvbnRleHQ8YnI+Cgo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140409/20140409090111183.jpg" alt="\">

上圖為OGNL Context的結構圖當struts2接受一個請求時,會迅速創建ActionContext,ValueStack,action。然後把action壓入到值棧中。所以action的實例變量可以被ognl訪問。所以利用ognl表達式可以訪問action。

ActionContext
\

從上面的代碼中可以看出來,struts2中的ActionContext的作用是提供了對ognl數

據的操作。並且可以通過ActionContext獲取到經過struts2封裝了的session等參數。

ServletActionContext
\

可以通過ServletActionContext得到servlet中的一些類,比如HttpServletRequest,ServletContext等可以通過ServletActionContext返回ActionContext

Ognl表達式

1.#號用法

訪問OGNL上下文和action上下文,#相當於ActionContext.getContext();如果訪問的是map中的值而不是對象棧中的值,由於map中的數據不是根對象,所以在訪問時需要添加#前綴。

名稱

作用

例子

parameters

包含當前HTTP請求的Map

#parameters.id[0]=request.getParameter(“id”)

request

包含當前HttpServletRequest屬性的Map

#request.username=request.getAttribute(“username”);

session

包含當前HttpSession屬性的Map

#session.username=session.getAttribute(“username”);

application

包含當前ServletContext屬性的Map

#application.username=application.getAttribute(“username”);

attr

用於按照request>session>application順序訪問其屬性

#attr.username相當於按照順序在以上三個范圍內讀取username的屬性,直到找到為止。


注:也可以寫為#request[‘username’] #sesssion[‘username’] #application[‘username’]

主要步驟:

在action中

\

在頁面中

\

2.用法2

OGNL會設定一個對象(root對象),在struts2中根對象就是CompoundRoot,或者為OgnlValueStack中的root,通常被叫做ValueStack(值棧或者對象棧),如果要訪問根對象的屬性,則可以省略去#,直接訪問對象的屬性即可。

在action中

\

在頁面中

3.用法3(深入理解對象棧)

有三個類:Person.java,Student.java,OgnlAction.java

Person類

\

Student類

\

OgnlAction類

\

把Person類和Student類創建出對象,然後放入到對象棧中,代碼為:


\


從以前學過的OGNLContext結構可以看出,對象棧中的分布如圖所示:

\

但是大家注意一個現象:在student對象中有comment屬性,在person對象中

也有comment屬性,在OgnlAction中還有comment屬性,如果頁面輸出

Comment屬性應該選擇哪種呢?

結論:

對於對象棧中存放的屬性,struts2會從最頂部開始尋找,如果找到則賦值,
如果找不到,則會依次往下尋找,直到找到為止。所以應該輸出的是student

對象的comment的值。

4.用法4(構造map)

還可以利用ognl表達式構造Map,如#{‘foo1’:’bar1’,’foo2’:’bar2’};這種用法經常用

在給radio,checkbox等標簽賦值上。

1、 在頁面上可以這樣輸出:

\

2、 也可以這樣使用:

\

\

5.用法5(%)

“%”符號的用途是在標簽的屬性值給理解為字符串類型時,執行環境%{}中添加的是OGNL表達式。

{}中用OGNL表達式

\

\

6.用法6($)

$主要有兩個用途:

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

在struts2的配置文件中引用OGNL表達式

在action中:

\

在配置文件中:

\

在頁面中:

\

標簽

Property標簽

default: 可選屬性,如果輸出的值為null,則顯示該屬性指定的值。 escape 可選屬性,指定是否格式化為html代碼 value 可選屬性,指定需要輸出的屬性值,如果沒有指定該屬性,則默認輸出ValueStack棧頂的值。

Debug標簽

利用debug標簽可以輸出OGNLContext所有的值

Set標簽

var: 變量的名字,name、id與var表達的含義是一樣的。Var已經取代了name,id; Scope: 指定變量被放置的范圍。該屬性可以接受application,session,request,page或Action。如果沒有設置該屬性,則默認會放在action中。 Value: 賦值給變量的值。如果沒有設置該屬性,則將ValueStack棧頂的值賦給變量。

Push標簽

把對象放入到棧頂,不能放入到其他的范圍,當標簽結束時,會從棧頂刪除。


Bean標簽

實例化一個符合javabean規范的class,標簽體內可以包含幾個param元素,可用於調用set方法,給class的屬性賦值。

Name: 要被實例化的class的名字,符合javabean規范。 Var: 賦值給變量的值。放置在request作用域中。如果沒有設置該屬性,對象被設置到棧頂。


Action標簽

通過指定命名空間和action的名稱,可以直接調用後台的action.

Name: Aciton的名字 Namespace: Action所在的命名空間(action的名稱後不加.action) executeResult: Action的result是否需要被執行,默認值為false,不執行

Iterator標簽

該標簽用於對集合進行迭代。這裡的集合包括:list,set和數組

Value: 可選屬性,指定被迭代的集合。如果沒有設置該屬性,則使用對象棧頂的集合。 Var: 可選屬性,引用變量的名稱 Status: 可選屬性,該屬性指定迭代時的IteratorStatus實例。該實例包含如下的方法: int getCount() 返回當前迭代的元素個數int getIndex() 返回當前迭代元素的索引boolean isEven() 返回當前迭代元素的索引是否是偶數boolean isOdd() 返回當前迭代元素的索引是否是奇數boolean isFirst() 返回當前迭代元素是否為第一個元素boolean isLast() 返回當前迭代元素是否為最後一個元素


If/else if/else標簽

基本的流程控制標簽。If標簽可以單獨使用,也可以結合elseif或else標簽使用。


test: 後面跟判斷表達式。

url標簽

該標簽用於創建url,可以通過”param”標簽提供request參數。

Value: 如果沒有值,就用當前的action,使用value後必須加.action. Action: 用來生成url的action.如果沒有使用則用value; Namespace: 命名空間 Var: 引用變量的名稱。

Ognl操作集合

Java代碼

OGNL表達式

list.get(0)

List[0]

array[0]

array[0]

((User)list.get(0)).getName()

list[0].name

Array.length

Array.length

List.size()

List.size

List.isEmpty()

List.isEmpty



Ognl操作Map

Java代碼

Ognl表達式

map.get(“foo”)

Map[‘foo’]

Map.get(new Integer(1));

Map[1]

User user = (User)map.get(“user”);

Return user.getName()

Map[‘user’].name

Map.size()

Map.size

Map.isEmpty()

Map.isEmpty

Map.get(“foo”)

Map.foo

Java代碼

Ognl表達式

Map map = new HashMap();

Map.put(“foo”,”bar”);

Map.put(“1”,”2”);

Return map;

#{“foo”:”bar”,”1”:”2”}

Map map = new HashMap();

Map.put(new Integer(1),”a”);

Map.put(new Integer(2),”b”);

Map.put(new Integer(3),”c”);

#{1:”a”,2:”b”,3:”c”}






  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved