1. 程式人生 > >Struts2學習(四)———— ognl表達式、值棧、actionContext之間的關系

Struts2學習(四)———— ognl表達式、值棧、actionContext之間的關系

需要 三種 查詢 哪些 tac 一次 詳細講解 大堆 存儲對象

一、什麽是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使用起來,就完了。

Struts2學習(四)———— ognl表達式、值棧、actionContext之間的關系