ValueStack称为值栈,有两个区域,一个内容(Content)区域,一个为上下文环境(Context)区域
值栈是控制器向前端页面传递数据的通道,在前端页面中就可以利用EL或者OGNL表达式读取ValueStack的值
案例如下(在struts中):
package cn.tedu.web;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.tedu.entity.Emp;
//测试值栈ValueStack
//值栈控制器向JSP页面传递数据的通道,在JSP中就可以利用EL表达式读取ValueStack的值
@Controller
@Scope("prototype")
public class StackAction {
private String message;
public String getMessage() {
return message;
}
private Map<String, Object> map;//用于测试map
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public void setMessage(String message) {
this.message = message;
}
private String[] arr; //用于测试数组
public String[] getArr() {
return arr;
}
public void setArr(String[] arr) {
this.arr = arr;
}
private Map<String, Object>[] data;//map数组
public Map<String, Object>[] getData() {
return data;
}
public void setData(Map<String, Object>[] data) {
this.data = data;
}
private List<Emp> list;//测试List
public List<Emp> getList() {
return list;
}
public void setList(List<Emp> list) {
this.list = list;
}
//测试两个相同的参数
private String texts;
public String getTexts() {
return texts;
}
public void setTexts(String texts) {
this.texts = texts;
}
public String execute(){
System.out.println("StackAction");
message = "Hello World";
//初始化map--用于测试
map = new HashMap<String, Object>();
map.put("name", "Tom");
map.put("age", 20);
map.put("user.address", "北京");
map.put("001", "狗蛋");
//初始化数组
arr = new String[3];
arr[0] = "今天";
arr[1] = "明天";
arr[2] = "后天";
//初始化map数组
data = new Map[2];//[null,null]
data[0] = new HashMap<String, Object>();
data[0].put("name", "Tom");
data[0].put("age", 20);
data[1] = new HashMap<String, Object>();
data[1].put("name", "Jerry");
data[1].put("age", 18);
//初始化list
list = new ArrayList<Emp>();
list.add(new Emp("Andy",10));
list.add(new Emp("John",15));
//测试相同的参数
texts = "ok";
return "success";
}
}
实体类Emp:
package cn.tedu.entity;
public class Emp {
private String name;
private int age;
public Emp(){};
public Emp(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Emp other = (Emp) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + "]";
}
}
struts.xml中的配置文件:
<action name="stack" class="stackAction">
<result name="success">
/WEB-INF/demo.jsp
</result>
</action>
demo.jsp如下:
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试值栈</title>
</head>
<body>
<h2>Value Stack 演示</h2>
<div>
<p>访问内容Content区域</p>
<p>1.使用 EL 表达式读取valueStack中的数据</p>
<p>
<!-- 普通 -->
${message }
<!-- map -->
${map.name}
${map.age}
<!-- map中特殊属性的读法 -->
${map['user.address']}<!-- 使用map.user.address会报错 -->
${map['001']}
<!-- 数组 -->
${arr[0] }
${arr[1] }
${arr[2] }
<br/>
<!-- 数组中含有map -->
${data[0].name }
${data[0].age }
${data[1]['name'] }
${data[1]['age'] }
<br/>
<!-- 集合中含有实体对象 -->
${list[0].name }
${list[0].age }
${list[1]['name'] }
${list[1]['age'] }
<!-- 测试相同参数 取第一个 -->
${texts }
</p>
<p>2.使用OGNL 读取valueStack中的数据</p>
<p>
<s:property value="message" /><!-- 也就是struts标签 value中的值就是OGNL表达式 -->
<s:property value="map.name" />
<s:property value="map.age" />
<s:property value="map['user.address']" />
<s:property value="map['001']" />
<s:property value="arr[0]" />
<s:property value="arr[1]" />
<s:property value="arr[2]" />
<br/>
<s:property value="data[0].name"/>
<s:property value="data[0].age"/>
<s:property value="data[1]['name']"/>
<s:property value="data[1]['age']"/>
<br/>
<s:property value="list[0].name"/>
<s:property value="list[0].age"/>
<s:property value="list[1]['name']"/>
<s:property value="list[1]['age']"/>
</p>
<hr/>
<p>访问上下文Context区域</p>
<p>request内容:本质是一个map</p>
<s:property value="#request" />
<p>request中struts.actionMapping的值:</p>
<s:property value="#request['struts.actionMapping']" />
<s:debug/>
</div>
</body>
</html>
访问地址:http://localhost:8000/struts_day03/stack
页面显示如下:
将[Debug]展开如下:
主要了解这两个区域,Content和Context区域,以及使用EL/OGNL 或 #加KEY来读取,因为Context区域本质上是一个map
Content只能使用EL表达式读取,Context只能使用OGNL表达式读取,且OGNL表达式是struts独有的
若Content中有两个相同的对象或参数,则在页面上显示的时候会取第一个值(例如:texts)