一、什么是ValueStack
ValueStack(值栈):是对应每一个请求对象的轻量级的内存数据中心,在内存中开辟的一块数据区。
Action不是单例的,所以每一次的action请求,都会创建一个新的ValueStack对象,该ValueStack对象封装了这一次请求相关的数据信息。
1).ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础。
2).ValueStack贯穿整个Action的生命周期(一次请求):每个Action类的实例都拥有一个ValueStack对象。 ValueStack相当于数据的中转站,在其中保存该次请求和当前Action对象和其他相关对象信息。
3).Struts2框架把ValueStack对象保存在名为“struts.valueStack”的request属性中。
新的请求发出后由struts2 框架完成以下创建:
ValueStack vs = Struts2框架创建ValueStack对象;
request.setAttribute("struts.valueStack",vs);
二、ValueStack内部结构
ValueStack对象中有两个很重要的属性,这两个属性就是ValueStack的主要内部结构:
root: 类型: List : 表示栈的数据结构(后进先出)
context: 类型: Map: 上下文
root:主要存储Action对象相关的数据信息,和用户手动存放在root区的数据
context:主要存储映射关系数据(key-value)。
每个HttpServletRequest对象中,都存放有“struts.valueStack”
三、Action中获取ValueStack
方式1: 因为ValueStack在请求中,属性名为:struts.valueStack.
ValueStack vs = request.getAttribute("struts.valueStack");
ValueStack vs = ServletActionContext.getRequest().getAttribute("struts.valueStack");
ValueStack vs = ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
方式2: 通过ActionContext对象获取
ValueStack vs = ActionContext.getContext().getValueStack();
以上两种方式获取的是同一个ValueStack对象.
四、将数据存放到ValueStack中
1)将数据存放到root中的方法
方式1:ValueStack对象.push(Object val); 这种方法没有名称,所以取出时用数组索引。
方式2:ValueStack对象.set(String propertyName,Object value);
方式3.在Action中提供一个可访问的属性(getter方法).
2)将数据存放到context中的方法
方式1:ValueStack对象.getContext().put(String key,Object value);
方式2:ActionContext对象.getContext().put(String key,Object value);
五、大JSP中取出ValueStack中的数据
需要使用Struts2的标签.
引入Struts2标签
<%@ taglib uri="/struts-tags" prefix="s"%>
Struts2的调试标签:<s:debug/> :主要用来观察数据在哪一个空间(root,context).
获取数据:<s:property value="OGNL表达式"/>
1).获取root中数据:
若:放入root中的数据,没有属性名:<s:property value="[0].top"/>
若:放入root中的数据有属性名: <s:property value="属性名"/>
2).获取context中数据:
<s:property value="#key"/>
3).访问结果
六、完整代码
1)action代码
package org.openbox.valuestack;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class StackAction extends ActionSupport {
private Integer age = 18;
//设字段属SET方法,struts2框架自动将值存放到root区域中
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
private String gender="woman";
public String getGender() {
return gender;
}
@Override
public String execute() throws Exception {
//0.首先要获得一个valuestack对象
ValueStack valueStack = ActionContext.getContext().getValueStack();
//1.将值存放到root list列表中
//1.1.方法1:
valueStack.push("xiao ming");
//1.2.方法2:
valueStack.set("name", "王宝强");
//2.将数据存放到context map中
//2.1.方法1
valueStack.getContext().put("name", "马小三");
//2.2.方法2
ActionContext.getContext().put("hobby","看电影");
return Action.SUCCESS;
}
}
2)jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ValueStack and OGNL</title>
</head>
<h3>ValueStack</h3>
<body>
debug信息:<s:debug /><br><br>
root区取值:<br>
1:<s:property value="[1].top"/><br>
2:<s:property value="name"/><br>
3:<s:property value="age"/><br>
<hr>
context区取值:<br>
1.<s:property value="#name"/><br>
2.<s:property value="#hobby"/>
</body>
</html>