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


      今天來說說ognl表達式在struts2中的運用。

                                  --WZY

一、什么是Ognl?

      通過百度百科查詢到的解釋,其中詳細的說明了OGNL的作用。

          

      下面我們就對OGNL這5個作用進行講解

      1、存取對象的任意屬性,簡單說就是對javabean進行操作(重要)

      2、調用對象方法。

      3、調用類的靜態方法

      4、索引數組元素

      5、操作集合(重 要)

 

二、OGNL的功能實現

      操作之前必須知道如何使用OGNL表達式,並且了解OGNL表達式的取值范圍只能在其context和root中,格式為

         Ognl.getValue(expression,context,root);

         //expression:為我們編寫的ognl表達式,從后兩個參數中獲取值,獲取規則會從下面的例子中詳細講解

         //context:ognl的上下文,類型為map,

         //root:ognl的根,可以為javabean、list、map、.... 等等很多值

      2.1、對javabean進行操作

        User.java

            

        Address.java

            

 

        獲取javabean中的屬性值

            

        獲取javabean中的對象的屬性值

                

        對javabean中的屬性進行賦值操作

            

         

 

      2.2、調用對象方法

             

      2.3、調用類的靜態方法或屬性

            

        

       2.4、索引數組元素

            

       2.5、操作集合

            操作list集合,list結合本質就是一個數組,所以從list中讀取數據跟對數組的操作是一樣的。

                  

            操作map集合

                  

            創建list集合

                  

            創建map集合

                  

         2.6、其他用法,使用數學運算符,使用“,”號連接表達式,in與not in運算符,投影、過濾等操作就不講解了,都非常簡單,重點掌握上面的即可。  

            

三、OGNL與struts2的結合

      上面說了那么一大堆的OGNL的使用功能,我們也感受到了他的強大,啥都能取出來,表達式啥都能做,但是在struts2中它是如何使用的呢?

      OGNL中的上下文即struts2中的actionContext

      OGNL中的root即struts2中的valueStack

      actionContext和valueStack是什么,他們之間什么關系?

      3.1、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.2、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.3、struts2不同的地方使用OGNL表達式獲取數據

          3.3.4、在jsp頁面中

              大部分都會在這里使用,因為jsp就是顯示數據的地方,在struts2中有很多s標簽,通過s標簽和OGNL表達式一起配置使用,就能拿到想要的數據了。而OGNL的表達式的編寫在最開始就已經講解過了,context就是actionContext,root就是valueStack,剩下表達式就看我們需要什么了。標簽的講解會在下一章

          3.3.5、在struts.xml中

              在struts.xml中有時候也需要用到OGNL表達式去拿一些數據。比如,在result中設置stream時,就需要從action中獲取流,而action可以看成是javabean,又在棧頂,所以直接使用OGNL表達式就能夠獲取到,但是注意特殊的,如果在你直接編寫ognl表達式時struts2不能夠區分出這是ognl表達式還是普通文本,那么就需要使用${}來表明該段文本是ognl表達式

              

 

 

四、總結

      struts2我覺得最重要的兩點,

            一、理解它的架構圖,知道大概的流程,

            二、該篇文章講解的值棧,actionContext,ognl的關系,

      這兩個弄懂了,基本上沒什么難得倒我們了,在寫三到四篇文章就可以把struts2給結束掉,還差的知識點有,s標簽的使用、國際化、還有文件上傳和下載的功能詳細講解,最后通過小項目將struts使用起來,就完了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM