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