Struts2的值栈(ValueStack),详解+图解

值栈的概述

1、什么是值栈

Struts2将XWork对Ognl的扩展这一套机制封装起来,这个对象叫ValueStack。
ValueStack实际上就是一个容器。
它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶。

ValueStack是Struts的一一个接口,字面意义为值栈,OgnIValueStack 是ValueStack 的实现类,客
户端发起一个请求struts2 架构会创建一个action 实例同时创建-一个OgnIValueStack 值栈实例,OgnlValueStack贯穿整个Action 的生命周期,struts2 中使用OGNL将请求Action的参数封装为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性值。

简化理解ValueStack其实类似一个数据的中转栈(Strust2框架当中的数据就都保存到了ValueStack中)
ValueStack接口,实现类OgnlValueStack的对象。
ValueSatck贯穿整个Action的生命周期。(Action一旦创建了,框架就会创建一个ValueStack对象)
放入值栈的数据可以在任何位置取出来(JSP、Servlet、Action、配置文件,在Struts2的任何地方都可以取到)

2、值栈的内部结构

ValueStack当中有两个主要的区域:

在这里插入图片描述

root区域: 其实就是一个ArrayList。里面一般放置的对象。获取root的数据是不需要加#
context区域:其实就是一个Map。里面放置的是Web开发的一些常用的对象数据的引用。获取的是context当中的数据是需要加#

requets:
session:
application:
parameters:
attr:
所说的操作值栈,通常指的是操作的是ValueStack当中的root区域。
创建一个类继承ActionSupport

public class ValueStackDemo1 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		//获得值栈的对象
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		return SUCCESS;
	}
}

设置跳转页面
在这里插入图片描述

<%@ 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>Insert title here</title>
</head>
<body>
	<h1>查看值栈的内部结构</h1>
	<s:debug></s:debug>
</body>
</html>

结果页面的数据
在这里插入图片描述

3、值栈与ActionContext的关系

ServletContext:Servlet的上下文。(贯穿整个应用的对象)

ActionContext:Action的上下文。(贯穿整个应用的对象)

通过源码查看到:当请求过来的时候,执行过滤器当中的doFilter方法,在这个方法当中创建ActionContext,
在创建ActionContext的过程当中,创建ValueStack对象,将ValueStack对象传递给ActionContext对象。
所以我们可以通过ActionContext来获取值栈的对象
ActionContext这个对象之所以能够访问到Servlet的API(访问的是域对象当中的数据)。因为在其内部有值栈的引用

//获得值栈的对象
ValueStack valueStack = ActionContext.getContext().getValueStack();

4、获得值栈

(1)第一种:通过ActionContext对象来获取值栈对象。

在Struts2内部,将值栈存入到request中一份。

// 第一种:通过ActionContext获得:
ValueStack valueStack = ActionContext.getContext().getValueStack();
(2) 第二种:通过request对象来获得
// 第二种:通过request对象来获得
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
(3) 测试两个对象是不是同一个对象

一个Action的实例,只会创建一个ValueStack的对象(一个ValueStack只会为一个Action服务)

public class ValueStackDemo2 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		// 第一种:通过ActionContext获得:
		ValueStack valueStack1 = ActionContext.getContext().getValueStack();
		// 第二种:通过request对象来获得
		ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest()
				.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
		System.out.println(valueStack1 == valueStack2);
		return NONE;
	}
}

浏览器访问
在这里插入图片描述
表示两个方式获取的Action是同一个值栈对象
在这里插入图片描述

5、操作值栈-向值栈当中存入数据(Root当中)

(1)第一种:在Action当中提供属性的get方法的方式。

默认的情况下,将Action对象压入到值栈。Action都在值栈当中,那么Action的属性一定也在值栈当中。

/*
 * 操作ValueStack:方式一:利用Action本身在值栈当中本身的特性。
 */
public class ValueStackDemo3 extends ActionSupport {
	private User user;
	public User getUser() {
		return user;
	}
	@Override
	public String execute() throws Exception {
		// 向ValueStack中去存值
		user = new User("李峰", "222");
		return SUCCESS;
	}
}

配置文件
在这里插入图片描述
jsp页面
在这里插入图片描述
可以在Root当中得到对应的user对象
在这里插入图片描述
在这里插入图片描述

(2)第二种:使用ValueStack当中本身的一些方法的方式。
import com.itzheng.struts2.domain.User;
import com.opensymphony.xwork2.ActionContext;
/*
 * 操作值栈:方式二:调用值栈当中的方法来进行实现。
 */
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ValueStackDemo4 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		//向值栈保存数据:
		//获得值栈对象
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		//一般会使用值栈当中的两个对象
		//使用push(Object obj); set(String key,Object obj);
		User user = new User("李四","121212");
		//压栈,user在栈顶的位置 
		valueStack.push(user);
		return super.execute();
	}
}

在这里插入图片描述
User在栈顶
在这里插入图片描述

注意:通过set的方式将输入放入到栈当中
谁最后调用谁就在最上面,创建了一个MAP集合,将MAP集合压入到栈当中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6、获取值栈的是数据

(1)获取root当中的数据:不需要加#

获取值栈当中数据就是在页面当使用OGNL表达式即可。
获取对象的数据
在这里插入图片描述
在这里插入图片描述
浏览器页面上
在这里插入图片描述
保存并获取集合当中的数据

public class ValueStackDemo5 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		// 向值栈当中保存对象
		User user = new User("aaa", "123");
		ActionContext.getContext().getValueStack().push(user);


		// 同值栈中保存一个集合
		List<User> list = new ArrayList<User>();
		list.add(new User("aaa", "111"));
		list.add(new User("bbb", "222"));
		list.add(new User("ccc", "333"));
		ActionContext.getContext().getValueStack().set("list", list);
		return super.execute();
	}
}

在这里插入图片描述
在这里插入图片描述

(2)获取context当中的数据:不需要加#

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)拓展内容

注意如果是arrt.name那么获取的是栈值当中的栈顶元素(也就是第一个元素)
在这里插入图片描述
parameters.id的作用是接收参加
在这里插入图片描述
在这里插入图片描述

7、EL为什么可以访问值栈的数据

因为Struts2的框架的底层对request.getAttribute(String name);

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44757034/article/details/106838688