值棧中root棧和context棧詳解

bianyamei發表於2017-08-25

OGNL只是顯示資料的表示式語言|ValueStack值棧才是所謂的儲存資料的


這裡寫圖片描述


這裡寫圖片描述

詳解 物件棧 root

①往物件棧(CompoundRoot extends ArrayList)中放資料 
②ActionContext.getContext().getValueStack().push(person);//把person物件放入到棧頂

放入棧頂的三個方法
 一:push()的原始碼是通過 getRoot().add(0,person)來完成放入棧頂
 二: ValueStack:
   root: 物件棧
      index:0   person
 三: ActionContext.getContext().getValueStack().set("person",person);
把person封裝成map,放入到棧頂
    ValueStack:
       root:物件棧
         index:0  Map:  key:"person" value:person
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

③ActionContext.getContext().getValueStack().add(person); 
把person放入到物件棧的底部

ValueStack:
   root:物件棧
    index:last(最後) person
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

④ActionContext.getContext().getValueStack().add(0,person); 
把person物件放入到物件棧指定的位置

ValueStack:
   root:物件棧
     index:0  person
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

詳解Map值棧如何存放資料

①通過map,request,session.application(requestMap,sessionMap.applicationMap)來存放資料

ServletActionContext.getRequest().setAttribute("req_a","a");
往map棧中的req域中存放資料

ValueStack:
   _values:Map
     key              value
     request          RequestMap
                      key      value
                     req_a       a

ActionContext.getContext().getSession().put("session_a","a");
往map棧中的session域中儲存資料

ValueStack:
   _values:Map
     key              value
     session          SessionMap
                      key          value
                     session_a       a

ServletActionContext.getServletContext().setAttribute("application_a","a");
往map棧中的application域存放資料

ValueStack:
   _values:Map
     key              value
    application          ApplicationMap
                          key               value
                     application_a             a

ActionContext.getContext().put("a","a");
直接往map棧中存放資料

ValueStack:
   _values:Map
     key              value
      a                 a
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

總結

  • ValueStack是ognl存放資料的物件
  • 得到ValueStack有三種方案 
    ActionContext.getContext().getValueStack() 
    ServletActionContext.getValueStack(request); 
    request.getAttribute(“struts.valueStack”);
  • ValueStack作用域為request
  • 當action建立的時候,ValueStack就建立了,當action被銷燬時,ValueStack就銷燬了
  • ValueStack可以利用物件棧和map棧存放資料
  • 向物件棧中存放資料 
    ActionContext.getContext().getValueStack().push 棧頂 物件 
    ActionContext.getContext().getValueStack().add() 棧底 物件 
    ActionContext.getContext().getValueStack().add(index,object); 按照指定的位置存放在物件棧中 
    ActionContext.getContext().getValueStack().set() 棧頂 Map
  • 向map棧中 
    request,session,application setAttibute() map–>_values—>requst,session,application 
    ActionContext.getContext().put(key,value) 直接存放在map棧中

如何利用OGNL表示式去ValueStack中的資料

  • 去棧頂的元素
  • 取棧頂的元素
  • s:iterator標籤的value屬性的值無論來自物件棧還是map棧,都可以不加#,s:select標籤也適合
  • 在s:iterator標籤迭代的時候,把當前正在迭代的元素放入到棧頂

屬性驅動: 
* 在action中,有屬性,屬性的名稱和頁面上form表單中的name的值對應 
* 屬性必須有set和get方法 
* 原理 
在提交一個請求以後,action中的屬性在棧頂。ParametersInterceptor攔截器 
會把頁面上的form表單的值獲取,然後調出ValueStack,給棧頂的屬性賦值。


模型驅動 
* StudentAction implements ModelDriver 
* 在action中需要有一個私有的物件 
private Student model = new Student(); 
* 原理 
* 先經過ModelDriverInterceptor,作用是把model放入到棧頂 
* 再經過ParametersInterrceptor,把棧頂的屬性賦值 
這兩個攔截器不能顛倒執行


action 中的棧的相關程式碼

public String getAllDepartment(){
        Collection<Department> departmentList = this.departmentService.getAllDepartment();
        //把departmentList放入到值棧中
        /**
         * 值棧
         *   *  值棧的生命週期
         *        值棧的生命週期就是一次請求
         *   *  值棧的資料結構
         *        物件棧
         *        map棧
         *   *  物件棧和map棧有什麼區別
         *        物件棧是一個list
         *        map棧是一個map
         *   *  怎麼樣把一個資料放入到map棧中
         *   *  怎麼樣把一個資料放入到物件棧中
         *          
         *   *  物件棧中的資料有什麼樣的特殊之處
         */
        //把departmentList放入到了物件棧的棧頂
        //ActionContext.getContext().getValueStack().push(departmentList);
        //把departmentList放入到了物件棧的棧頂
        //ActionContext.getContext().getValueStack().getRoot().add(0, departmentList);
        //把departmentList放入到了物件棧的棧底
        //ActionContext.getContext().getValueStack().getRoot().add(departmentList);
        //獲取物件棧的棧頂的元素
        //ActionContext.getContext().getValueStack().peek();
        //移除物件棧的棧頂的元素
        //ActionContext.getContext().getValueStack().pop();
        //移除物件棧的棧頂的元素
        //ActionContext.getContext().getValueStack().getRoot().remove(0);
        //把一個map放入到物件棧的棧頂
        //ActionContext.getContext().getValueStack().set(key, o);
        /**
         * 物件棧的說明
         *    *  處於物件棧的物件中的屬性是可以直接訪問的
         *    *  如果在物件棧中有一樣名稱的屬性,從棧頂開始查詢,直到找到為止
         *    *  一般情況下,回顯的資料應該放在物件棧中,這樣效果比較高
         *    *  用ognl表示式訪問物件棧,直接屬性名稱就可以了,不用加#
         */

        //map棧
        /**
         * 說明
         *   *  reuqest,session,application都在map棧中
         *   *  可以把一個物件放入到map中
         *   *  ognl表示式訪問map棧中的內容
         *       如果一個物件在request中
         *          #request.物件的key值.屬性
         *       如果一個物件直接放入到map中
         *          #物件的key值.屬性
         *       把一個物件放入到map棧中,是不能直接訪問該物件的屬性
         */
        //把一個物件存放到map棧中
        ActionContext.getContext().put("departmentList", departmentList);
        //#request.deparmentList
        //ServletActionContext.getRequest().setAttribute("departmentList", departmentList);
//      List<List<Department>> lists = new ArrayList<List<Department>>();
//      Department department1 = new  Department();
//      department1.setDname("department1_name");
//      Department department2 = new  Department();
//      department2.setDname("department2_name");
//      List<Department> departmentList1 = new ArrayList<Department>();
//      departmentList1.add(department1);
//      List<Department> departmentList2 = new ArrayList<Department>();
//      departmentList2.add(department2);
//      lists.add(departmentList1);
//      lists.add(departmentList2);
//      
//      List<Map<String, Department>> lists2 = new ArrayList<Map<String,Department>>();
//      Map<String, Department> map1 = new HashMap<String, Department>();
//      map1.put("d1", department1);
//      Map<String, Department> map2 = new HashMap<String, Department>();
//      map2.put("d2", department2);
//      lists2.add(map1);
//      lists2.add(map2);
//      
//      Map<String, List<Department>> maps = new HashMap<String, List<Department>>();
//      maps.put("list1", departmentList1);
//      maps.put("list2", departmentList2);
//      ActionContext.getContext().put("maps", maps);
        return listAction;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

jsp頁面取值相關程式碼

 <tbody id="TableData" class="dataContainer" datakey="departmentList">
            <!-- 
                iterator說明
                  *  將當前正在迭代的元素放在棧頂
                  *  如果value屬性不寫,則預設迭代棧頂的元素
                  *  value值如果為top,則也是迭代棧頂的元素
             -->

            <s:iterator value="#departmentList">
                <tr class="TableDetail1 template">
                    <td><s:property value="dname"/></td>
                    <td><s:property value="description"/></td>
                    <td>
                        <!-- 
                            在struts2的標籤中只能用ognl表示式,不能用el表示式
                            在html標籤中,只能用el表示式,不能用ognl表示式
                         -->
                        <s:a action="departmentAction_deleteDepartment?did=%{did}">刪除</s:a>
                        <a href="saveUI.html">修改</a>
                    </td>
                </tr>
            </s:iterator>

             <!-- 
                list中含有list
              -->
              <!-- 
              <s:iterator>
                <s:iterator>
                    <s:property value="dname"/>
                </s:iterator>
              </s:iterator>
               -->
              <!-- 
                list中含有map
               -->
               <!-- 
               <s:iterator value="#list">
                  <s:iterator value="top">
                    <s:property value="key"/>
                    <s:property value="value.dname"/>
                  </s:iterator>
               </s:iterator>
                -->
                <!-- 
                    map中含有list
                 -->
                 <!-- 
                 <s:iterator value="#maps">
                    <s:property value="key"/>
                    <!-- 
                        該迭代就是一個list
                     -->
                    <!-- 
                    <s:iterator value="value">
                        <s:property value="dname"/>
                    </s:iterator>
                 </s:iterator>
                  -->

相關文章