Struts2值栈ValueStack介绍

ValueStack(值栈): 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack对象,每次请求都会创建一个Action类)。请求完成后ValueStack与request将一起消失。

ValueStack相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象.

ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础

Struts框架把ValueStack对象保存在名为“struts.valueStack” 的请求属性中,request中ServletActionContext类中提供了一个常量
public static final String STRUTS_VALUESTACK_KEY = “struts.valueStack”;

值栈的获取:

//获取方式一
ValueStack valueStack = ActionContext.getContext().getValueStack();
//获取方式二
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		

在 ValueStack 对象的内部有两个逻辑部分:
ObjectStack: Struts把动作和相关对象压入ObjectStack中,底层实现对象为CompoundRoot, CompoundRoot是一个ArrayList
ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中。底层为Map

对值栈的操作,默认都是Root对象的操作,访问数据时不需要使用#号
Struts 会把下面这些映射压入 ContextMap 中,获取时间是需要使用#号
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application

ValueStack内部底层图解分析:
这里写图片描述

OgnlValueStack 类包含两个重要的属性:一个root和一个context。
其中root本质上是一个ArrayList.
而context 是一个Map(更确切的说是一个OgnlContext对象)
在这个OgnlContext对象(context)中,有一个默认的顶层对象_root,OGNL访问context中这个默认顶层对象中的元素时,是不需要#号的,直接通过元素的名称来进行访问,而访问其他对象时,如 request、session、attr等,则需要#号引用。

Struts2将OgnlValueStack的root对象赋值给了OgnlContext中的_root对象,在OgnlValueStack的root对象中,保存着调用Action的实例,因此,在页面上通过Struts2标签访问Action 的属性时,就不需要通过#号来引用

总结:ognl Context包含 ObjectStack属性和ContextMap属性

当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。

ServletActionContext.getRequest()
                       .setAttribute("username", "username_request");
ServletActionContext.getContext().getSession()
                       .put("username", "username_session");
ServletActionContext.getServletContext()
                       .setAttribute("username", "username_application");

ActionContext提供了对ognl上下文对象中数据操作的方法.
valueStack = ServletActionContext.getContext().getValueStack();

valueStack.set("username", "username_valueStack");
valueStack.push(new User("u001", "zhangsan", "12345"));

值栈的使用示例:
action类:

package com.my.action;

import com.my.bean.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.util.ValueStack;

public class ValueStackAction extends ActionSupport implements ModelDriven<User> {
	
	private User user = new User();

	@Override
	public String execute() throws Exception {
		//获得值栈
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		// 给context 存放数据
		ActionContext.getContext().put("ac", "request_ValueStack"); //给Map栈中存放数据
		ActionContext.getContext().getSession().put("ac", "session_ValueStack"); //将数据存放在context Map中 key为session ,value = entry(key = value)
		ActionContext.getContext().getApplication().put("ac", "application_ValueStack");
		
		// 将栈顶的数据弹出
		// valueStack.pop();
		User user = new User();	//查询结果
		user.setUsername("zhangsan");
		user.setPassword("1234");
		this.user = user;
		
		return SUCCESS;
	}

	@Override
	public User getModel() {
		return this.user ;
	}

}

action配置:

<action name="valueStackAction" class="com.my.action.ValueStackAction">
    		<result name="success">/success.jsp</result>
    	</action>

valueStack.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="${pageContext.request.contextPath}/valueStackAction" method="post">
		用户名:<input type="text" name="username" /> <br/>
		密码:<input type="text" name="password" /> <br/>
		<input type="submit" value="提交" />
	</form>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  <br/>
  <s:debug></s:debug>
  
  <!-- 从context获得数据 -->
  <s:property value="#ac"/> <br/>
  <s:property value="#session.ac"/> <br/>
  <s:property value="#application.ac"/> <br/>
  
  <hr/>
  <!-- 使用el获取内容 -->
  ${requestScope.ac} <br/> 	<!-- struts 对request的getAttribute方法进行增强,先从request获取内容,再从值栈从获取内容 -->
  <% request.getAttribute("ac"); %> <br/>
  <%=request %> <br/>
  
  <!--  -->
   <s:property value="ac"/> <br/> <!-- 先从root栈中获取内容,再从map栈获取内容 -->
   ###<s:property value="#request.ac"/> <br/>
   
   <hr/>
   <!-- 可以显示表单提交的数据 -->
   <s:property value="username"/> <br/>
   <s:property value="password"/> <br/>
   
   <!-- Action中执行了valueStack.pop(); -->
   <s:property value="model.username"/> <br/>
   <s:property value="model.password"/> <br/>
</body>
</html>

运行结果:
这里写图片描述

struts2提供了一个<s:debug></s:debug>标签可以对值栈进行详细的显示。
运行结果:
这里写图片描述
这里写图片描述

Coding Diary

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值