值栈中root栈和context栈详解

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

③ActionContext.getContext().getValueStack().add(person); 
把person放入到对象栈的底部

ValueStack:
   root:对象栈
    index:last(最后) person

④ActionContext.getContext().getValueStack().add(0,person); 
把person对象放入到对象栈指定的位置

ValueStack:
   root:对象栈
     index:0  person

详解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

总结

  • 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;

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>
                  -->
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值