概述
什么是值栈
值栈: ValueStack
当浏览器访问action的时候,会被前端控制器(StrutsPrepareAndExecuteFilter)拦截住,在filter中创建值栈(ValueStack)对象(特点:访问一次,创建一次)
创建完以后,会将访问的整个action对象放在ValueStack中,还会将request,session,servletContext对象的底层用来存储数据的map数据集合放在ValueStack中
还会将当前页面提交的所有数据以map的方式也存放在ValueStack中(ps:存放的都是地址引用)
当整个action执行完毕,action对象会被销毁,ValueStack对象也会被销毁下次访问又是一个新的aciton对象和新的ValueStack对象
也就是说:aciton的生命周期和ValueStack是同步的,ValueStack会伴随action一生
ValueStack: 是struts2提供了一个接口 真正的实现类是:OgnlValueStack
问题: ValueStack是有谁创建的,又是什么时候创建的 ?
当浏览器访问action的是时候,会被前端控制器给拦截住(StrutsPrepareAndExecuteFilter)
在前端控制器中,自动创建ValueStack对象(特点: 访问一次action,创建一次ValueStack对象)
当值栈对象被创建出来之后,会将当前访问的action对象整个放在值栈
还会将request,session,servletContext的底层用来封装数据的map集合也放在值栈中
(特点:放的是地址引用)
当整个action执行完毕后,action会销毁,值栈也跟着销毁
下一次再访问,又是一个新的action对象和一个新的值栈对象
所以:值栈的生命周期是伴随action一生的
值栈的内部结构?
1 获取值栈打断点来看的
2 通过struts2的内置标签可以将整个值栈结构的数据显示页面:<s:debug></s:debug>
ActionContext与值栈的关系? (为什么就能通过ActionContext获取值栈对象)
当浏览器访问action的时候,会创建值栈对象,还会创建ActionContext对象
最后把整个值栈放在actionContext中,然后把整个actionContext与当前线程
绑定
问题:怎么保证action中获取的actionContext就是自己的 不是别人的?
将整个actionContext放在当前线程中 进行传递
threadLocal(当前线程,actionContext);
值栈的获取方式
ActionContext.getContext.getValueStack()
如何操作ValueStack?
1 往ValueStack的root区域存数据
1 action的属性方式 (掌握) 99%(set方式)
action的成员属性数据都会在root区域中
因为整个action都在值栈中
package com.it.action;
import java.util.ArrayList;
import java.util.List;
import com.it.bean.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ActionDemo1 extends ActionSupport{
// 放在root区域了 因为整个ActionDemo1都在root区域
private String username;
private List list =new ArrayList();
private User user =new User();
public String getUsername() {
return username;
}
public List getList() {
return list;
}
public User getUser() {
return user;
}
@Override
public String execute() throws Exception
{
// 往值栈的root区域存数据
username="zhangsan";
user.setAge(18);
user.setUsername("tom");
list.add(13);
list.add("ddd");
// 获取值栈的数据 当前action的username属性(了解)
//
ValueStack vs = ActionContext.getContext().getValueStack();
//
Object obj = vs.findValue("username"); // 根据属性 (Property Name)
//
System.out.println(obj);
//
return "success";
}
}
jsp界面代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s"
uri="/struts-tags"%>
<!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>
<!-- 通过struts2的内置标签 将整个值栈的内部结构图在页面显示 -->
<s:debug></s:debug>
<!-- 通过ognl获取值栈的数据 当前action的username属性(掌握)
类似调用这个方法:vs.findValue(Property Name);
-->
<!-- 基本数据类型 -->
<s:property value="username"/><br>
<hr>
<!-- 对象 -->
<s:property value="user.username"/>
<s:property value="user.age"/>
<!-- list集合 -->
<s:property value="list[0]"/>
<s:property value="list[1]"/>
<hr>
<!--遍历list集合
-->
<s:iterator value="list" var="i">
<s:property value="#i"/> <br>
</s:iterator>
</body>
</html>
2 ValueStack的API的方式(push方式)
push(Object obj) push对象 存对象 (掌握)
ValueStack.push(); 对象用push
底层:
getRoot() 获证整个root区 (不用 理解的)
ValueStack.getRoot().push()
java代码
package com.it.action;
import java.util.ArrayList;
import java.util.List;
import com.it.bean.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.ValueStack;
public class ActionDemo2 extends ActionSupport{
// 往值栈的root区域存数据 值栈的API方式
@Override
public String execute() throws Exception {
User user = new User();
user.setUsername("jack");
user.setAge(18);
String name="tom";
List list=new ArrayList();
list.add(123);
list.add("avd");
//
ValueStack vs = ActionContext.getContext().getValueStack();
//
CompoundRoot root = vs.getRoot();
//
root.push(user);/ //在栈顶
底层:add(0, o);
ValueStack vs = ActionContext.getContext().getValueStack();
vs.push(name);
vs.push(user);
vs.push(list);//手动压栈顶最后一个保存的在最上面(后进先出)
return "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>
<!-- 通过struts2的内置标签 将整个值栈的内部结构图在页面显示 -->
<s:debug></s:debug>
<!-- 通过Property Name来获取数据
-->
<!--获取基本类型数据
-->
<s:property value="[2].top"/><br>
<hr>
<!--获取对象
-->
<s:property value="username"/><br>
<s:property value="age"/><br>
<hr>
<!-- 获取集合 -->
<s:property value="[0].top"/><br>
<hr>
<!--遍历list
-->
<s:iterator value="[0].top" var="i">
<s:property value="#i"/>
</s:iterator>
</body>
</html>
2 往ValueStack的context区域存数据
package com.it.action;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ActionDemo3 extends ActionSupport {
@Override
public String execute() throws Exception {
// 往值栈的context区域存数据
ActionContext context = ActionContext.getContext();
Map<String, Object> map = context.getSession();
map.put("msg1", "session....");
Map<String, Object> map2 = context.getApplication();
map2.put("msg2", "servletContext...");
// 自定义context区域的key和value
context.put("msg", "msggggggggggggg");
return "success";
}
}
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s"
uri="/struts-tags"%>
<!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>
<!-- 通过struts2的内置标签 将整个值栈的内部结构图在页面显示 -->
<s:debug></s:debug>
<!-- 获取xcontext区域的数据
-->
<s:property value="#session.msg1"/><br/>
<s:property value="#application.msg2"/><br/>
<s:property value="#attr.msg1"/>---<s:property value="#attr.msg2"/><br/>
<s:property value="#msg"/>
<hr/>
<!-- 值栈的数据也可以用el获取到 -->
${sessionScope.msg1 }<br/>
${applicationScope.msg2 }<br/>
${requestScope.msg }--->${msg}<br/>
</body>
</html>
el也可以获取到值栈中的数据
<!-- el的方式来获取Context数据(了解) -->
${sessionScope.sessionmsg} --->${sessionmsg }<br/>
${applicationScope.contextmsg} --->${contextmsg }<br/>
${requestScope.requestmsg} ---${requestmsg }<br/>
el ${属性名} 以前依次从 pageContext,request,session,application查找
底层:
之前的el的${msg1}
先调用pageContext.getAttribute(..)
获取到,立即返回
获取不到,继续调用
request.getAttribute(..) struts2增强了
获取到,立即返回
获取不到,获取root区找,root区回去context区找
如果都没找到 继续调用
session.getAttribute(..)
获取到,立即返回
获取不到,继续调用
application.getAttribute(..)
获取到,立即返回
获取不到,返回""
在struts的el的底层:装饰者模式
包装了request.对request.getAttribute方法进行了增强.
先依次以以前的方式查询
若都没有查询到,调用了 valueStack.findValue(..)从值栈中查找
以前的: pageContext,request,session,application
struts包装以后
最终: pageContext,request,root区,context区,session,application
小小的总结三种方式如有错误,欢迎大家指出
最后
以上就是秀丽电脑为你收集整理的Struts2值栈,从值栈中获取数据,root区set和push方式和context区获取方式的全部内容,希望文章能够帮你解决Struts2值栈,从值栈中获取数据,root区set和push方式和context区获取方式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复