今天來講說ognl表達式在struts2中的運用。java
--WZYexpress
1、什麼是Ognl?數組
經過百度百科查詢到的解釋,其中詳細的說明了OGNL的做用。session
下面咱們就對OGNL這5個做用進行講解架構
一、存取對象的任意屬性,簡單說就是對javabean進行操做(重要)app
二、調用對象方法。jsp
三、調用類的靜態方法spa
四、索引數組元素3d
五、操做集合(重 要)xml
2、OGNL的功能實現
操做以前必須知道如何使用OGNL表達式,而且瞭解OGNL表達式的取值範圍只能在其context和root中,格式爲
Ognl.getValue(expression,context,root);
//expression:爲咱們編寫的ognl表達式,從後兩個參數中獲取值,獲取規則會從下面的例子中詳細講解
//context:ognl的上下文,類型爲map,
//root:ognl的根,能夠爲javabean、list、map、.... 等等不少值
2.一、對javabean進行操做
User.java
Address.java
獲取javabean中的屬性值
獲取javabean中的對象的屬性值
對javabean中的屬性進行賦值操做
2.二、調用對象方法
2.三、調用類的靜態方法或屬性
2.四、索引數組元素
2.五、操做集合
操做list集合,list結合本質就是一個數組,因此從list中讀取數據跟對數組的操做是同樣的。
操做map集合
建立list集合
建立map集合
2.六、其餘用法,使用數學運算符,使用「,」號鏈接表達式,in與not in運算符,投影、過濾等操做就不講解了,都很是簡單,重點掌握上面的便可。
3、OGNL與struts2的結合
上面說了那麼一大堆的OGNL的使用功能,咱們也感覺到了他的強大,啥都能取出來,表達式啥都能作,可是在struts2中它是如何使用的呢?
OGNL中的上下文即struts2中的actionContext
OGNL中的root即struts2中的valueStack
actionContext和valueStack是什麼,他們之間什麼關係?
3.一、ActionContext和valueStack(重要)
ActionContext:
充當OGNL的context。是action的上下文,也能夠叫作action的數據中心,本質是一個map,在其中,全部的數據都存放在這裏,那其中到底存放了哪些東西呢,actionContext中存放數據的方式又是怎樣的?
actionContext是一個map,因此其中都是以鍵值對的形式存儲對象,以下圖所示,
request、session、application這種咱們熟知的做用域,注意是做用域,而不是對象,
paramters:這個是表單提交的參數,所有都會放到這個map中,
attr(attributes):三個做用域全部的屬性都會放在該map下,若是有重複的,那麼以request域中的爲準。
VALUE_STACK:值棧,存放着valueStack對象,也就是說,經過ActionContext可以獲取到valueStack。
若是咱們使用actionContext.put(); 那麼會將該鍵值對直接放入到ActionContext下,
注意:除了request外,其餘均可以直接經過getXxx()得到。而想要獲取request做用域,必須經過key值的方式來獲取。ActionContext.getContext().get("request"); 爲何這樣呢?由於struts2對request進行了加強。從這裏actionContext中是不能直接獲取到的,request進行了怎樣的加強呢?好比在actionContext中put了一個普通的key和value,該鍵值對並無在request域中,可是在jsp中,經過在request域查找key,也能找到該鍵值對,底層進行了兩步:第一步:從request域中查找數據,第二步:若是沒有找到,將從值棧中執行findValue()。 這樣就解釋了爲何經過ActionContext不能直接獲取request,而且爲何不在request做用域中的數據,而經過在request域中查找也可以獲取到。
valueStack:值棧,本質是一個ArrayList,做用,充當ognl的root,給一次請求中共享數據的功能。
內部圖
root:源碼中的名稱爲CompoundRoot,它也是一個棧,而每次值棧中入棧和出棧等操做其實就是對CompoundRoot進行對應的操做。
Context:對actionContext的引用,也就是經過valueStack也可以獲取到上下文,經過getContext();
在咱們訪問一個action時,會將action加入到棧頂,也就是action會在CompoundRoot的棧頂,而咱們提交的各類表單參數(充當了ognl表達式)會在valueStack從頂向下查找對應的屬性進行賦值。這就是值棧的做用。
值棧的操做
這裏提一下,知道了值棧的內部結構圖,那麼就好理解了。
action中手動向valueStack中放數據。
ActionContext.getContext().getValueStack().push(xxx); //通常是javabean,這樣放是放在root中,由於push操做是對棧進行操做,也就是對root進行操做
ActionContext.getContext().getValueStack().set(key,value); //任意值,以key-value的形式放入到了root中。
jsp獲取
push存放,在root下,直接使用屬性獲取便可
set存放,經過屬性也能夠直接得到。這裏要排除一個誤區,就是不要以爲set方式是以鍵值對的方式存放,就以爲是放入了context中,並無,仍是在root中鍀
context操做
ActionContext.getContext().put(key,value); //存放在actionContext中,也就是OGNL的context中
JSP獲取:三種方式進行獲取
#key獲取。
直接使用key獲取,由於值棧中也有context。只不過要從棧頂中的root開始找,而後在從context中查找
#request獲取。由於struts2對request進行了加強,若是request域中找不到,則使用findValue(),從值棧中的root開始一路往下找。
3.二、ActionContext和valueStack的關係(重要)
你中有我,我中有你。
也就是說,經過valueStack能夠獲取到actionContext,經過ActionContext也能夠獲取到valueStack。
valueStack是對root進行操做,而actionContext是對context進行操做。(root和context是OGNL中的根和上下文)
獲取值棧的方式:
ActionContext.getContext.getValueStack();//經常使用
ActionContext.getContext.get("VALUE_STACK");
request.getAttribute("VALUE_STACK"); //這個爲何能夠?由於request進行了加強。詳情看上面的解釋。
獲取actionContext的方式
ActionContext.getContext(); //經常使用
valueStack.getContext();
3.三、struts2不一樣的地方使用OGNL表達式獲取數據
3.3.四、在jsp頁面中
大部分都會在這裏使用,由於jsp就是顯示數據的地方,在struts2中有不少s標籤,經過s標籤和OGNL表達式一塊兒配置使用,就能拿到想要的數據了。而OGNL的表達式的編寫在最開始就已經講解過了,context就是actionContext,root就是valueStack,剩下表達式就看咱們須要什麼了。標籤的講解會在下一章
3.3.五、在struts.xml中
在struts.xml中有時候也須要用到OGNL表達式去拿一些數據。好比,在result中設置stream時,就須要從action中獲取流,而action能夠當作是javabean,又在棧頂,因此直接使用OGNL表達式就可以獲取到,可是注意特殊的,若是在你直接編寫ognl表達式時struts2不可以區分出這是ognl表達式仍是普通文本,那麼就須要使用${}來代表該段文本是ognl表達式
4、總結
struts2我以爲最重要的兩點,
1、理解它的架構圖,知道大概的流程,
2、該篇文章講解的值棧,actionContext,ognl的關係,
這兩個弄懂了,基本上沒什麼可貴倒咱們了,在寫三到四篇文章就能夠把struts2給結束掉,還差的知識點有,s標籤的使用、國際化、還有文件上傳和下載的功能詳細講解,最後經過小項目將struts使用起來,就完了。