struts2(四) ognl表達式、值棧、actionContext之間的關係

      今天來講說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使用起來,就完了。

相關文章
相關標籤/搜索