ValueStack

1 什么是ValueStack?

Struts2将XWork对Ognl的扩展这一套机制封装起来,这个对象叫ValueStack(即值栈),其实ValueStack是Struts2的一个接口OgnlValueStackValueStack的实现类,客户端发起一个请求时,Struts2会创建一个action的实例并同时创建一个OgnlValueStack的值栈实例,OgnlValueStack贯穿了整个action的生命周期,struts2中使用OGNL请求action的参数封装为对象存储在值栈中,并通过OGNL表达式读取值栈中的对象属性值

2 值栈的简要概括

ValueStack是一个容器,其实就类似于一个数据中转站(Struts2框架中的数据就都保存到了ValueStack

(1)valuestack是接口OgnlValueStack是接口的实现类

(2)ValueStack贯穿整个Action生命周期Action一旦创建了,框架就会创建一个valueStack对象)

注意:只要存入值栈,在任何地方都能取出数据(可以在页面,可以在Action,可以在配置文件中),之前的在request中存入数据,只能在jsp页面中取出数据

3 值栈的内部结构

ValueStack中最重要的两个区域:root区域context区域

root区域(CompoundRoot):其实就是一个ArrayList,里面放置的是一个对象,获得root区域的数据不需要加#


package com.opensymphony.xwork2.util;

import java.util.ArrayList;
import java.util.List;

public class CompoundRoot extends ArrayList {

    public CompoundRoot() {
    }

    public CompoundRoot(List list) {
        super(list);
    }


    public CompoundRoot cutStack(int index) {
        return new CompoundRoot(subList(index, size()));
    }

    public Object peek() {
        return get(0);
    }

    public Object pop() {
        return remove(0);
    }

    public void push(Object o) {
        add(0, o);
    }
}

 Context区域:其实就是一个Map。里面放置的是web开发的常用的对象数据的引用,获取context对象的需要加#

(1)request(2)session(3)application(4)parameters(5)attr

4 值栈与ActionContext的关系 

  • ServletContext:Servlet的上下文
  • ActionContext:Action的上下文
  • 通过源码查看到:当请求过来的时候,执行核心过滤器中的dofilter方法,在这个方法中创建ActionContext在创建ActionContext过程中,创建ValueStack对象,将ValueStack对象传递给ActionContext对象。所以可以通过创建ActionContext获得值栈对象。
  • ActionContext对象之所以能够访问Servlet的API(访问的是域对象的数据,而不是真实的域对象)。因为在其内部有值栈的引用

5 值栈的获得

5.1 通过ActionContext对象获得值栈

ValueStack valueStack1 = ActionContext.getContext().getValueStack();

5.2 通过request对象获得值栈

//有两种方式
//第一种
 ValueStack valueStack = (ValueStack)ServletActionContext.getRequest().
getAttribute("struts.valueStack");
//第二种
 ValueStack valueStack = (ValueStack)ServletActionContext.getRequest().
getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

6 操作值栈

所谓的操作值栈,通常指的是操作valuestack中的root区域

6.1 向值栈中存入数据

6.1.1 在Action中提供属性的get方法

  • Action类的写法
package com.itykd.web.action;

import com.itykd.domain.User;
import com.opensymphony.xwork2.ActionSupport;

public class ValueStackDemo extends ActionSupport{
	private User user;
	
     public User getUser() {
		return user;
	}

	public String execute() {
         user = new User("ykd","1111111");
    	 return SUCCESS;
     }
}
  •  jsp页面
<body>
    <h3>方式一:利用Action在值栈中的特性</h3>
    <s:property value="user.username"/><br/>
    <s:property value="user.password"/>
</body>

6.1.2 使用ValueStack中本身的方法的方式(调用值栈的方法实现)

  • Action类
package com.itykd.web.action;

import com.itykd.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

public class ValueStackDemo2 extends ActionSupport{

	public String execute() {
         //向值栈中保存数据
		//获得值栈对象
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		//使用push(Ojbect obj)或者set(String key,Ojbect obj)
		User user = new User("ykd","222222");
		//将user对象压入值栈后,user位于栈顶
		valueStack.push(user);
    	 return SUCCESS;
     }
}
  • jsp页面
<body>
    <h3>方式二:调用值栈的方法实现</h3>
    <s:property value="username"/><br/>
    <s:property value="password"/>
    <s:debug></s:debug>
</body>

可以利用<s:debug></s:debug>看到,目前的User对象已经在值栈的栈顶 

6.2  获得值栈数据

获取值栈中的数据就是在页面中使用OGNL表达式即可

6.2.1 获得root的数据(不需要加#)

  • Action类
package com.itykd.web.action;

import java.util.ArrayList;
import java.util.List;

import com.itykd.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

public class ValueStackAction extends ActionSupport{
    public String execute() {
    	//向值栈中保存一个对象
    	User user = new User("ykd", "13e123");
    	ValueStack valueStack = ActionContext.getContext().getValueStack();
    	valueStack.push(user);
    	//向值栈中保存一个List集合
    	List<User> list = new ArrayList<>();
    	list.add(new User("kobe","244645646"));
    	list.add(new User("Jordan", "23464654"));
    	list.add(new User("Duncan", "211e43dafd"));
    	valueStack.set("userList", list);
    	return SUCCESS;
    }
}
  • jsp页面
<body>
    <h3>获得对象的数据</h3>
    <s:property value="username"/>
    <s:property value="password"/>
    <h3>获得集合中的数据</h3>
    <s:property value="userList[0].username"/>
    <s:property value="userList[0].password"/>
    <s:property value="userList[1].username"/>
    <s:property value="userList[1].password"/>
    <s:property value="userList[2].username"/>
    <s:property value="userList[2].password"/>
</body>

6.2.2 获得context对象的数据(需要加#)

  • Action类
package com.itykd.web.action;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class ValueStackAction2 extends ActionSupport{
	    public String execute() {
	    	//向context中存入数据
	    	ServletActionContext.getRequest().setAttribute("name", "ykd");
	    	ServletActionContext.getRequest().getSession().setAttribute("name", "Kobe");
	    	ServletActionContext.getServletContext().setAttribute("name", "Jordan");
	    	return SUCCESS;
	    }
}
  • JSP页面 
<body>
    <h3>向context中取数据</h3>
    <s:property value="#request.name"/>
    <s:property value="#session.name"/>
    <s:property value="#application.name"/>
    <s:property value="#attr.name"/>
</body>

注意:attr.name会依次判断request、session、application域对象中是否有数据。如果有,则显示对应的数据

7 EL为何访问值栈数据

因为Struts2框架的底层对request.getAttribute(String name)进行了增强(StrutsRequestWrapper.class

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值