值栈ValueStack
1.值栈的概念:
值栈是struts2提供的一个存储数据的对象,类似于web项目中的request域,使用值栈存储数据,result标签的type属性必须为dispatcher
2.Servlet和Action的区别:
* Servlet,默认情况下当用户第一次访问时创建一个实例,用户每次访问都会调用Servlet的service方法,但是Servlet是单例的
* Action,用户每访问一次Action,都会创建一个新的Action实例,Action是多例的,每个Action对象中都存在一个值栈对象
3.获取值栈对象(每个Action对象中都有且仅有唯一的一个值栈对象):
ActionContext actionContext = ActionContext.getContext();
ValueStack valueStack = actionContext.getValueStack();
4.值栈内部结构:
值栈内部结构分为两部分:
* root:(实际上是一个List集合),存储数据通常都是操作root,主要存储Action对象中的数据,也叫对象栈
CompoundRoot extends ArrayList
* context:(实际上是一个Map集合),主要存储web中的域对象,key名称是固定的request、session、application、parameters、attr
OgnlContext implemetns Map
5.查看值栈内部结构:
(1)在jsp页面引入struts标签库
<%@ taglib prefix="s" uri="/struts-tags" %>
(2)使用debug标签查看,栈顶默认是Action类的引用(地址值)
<s:debug></s:debug>
6.向值栈中存储数据
* 方式一: 获取值栈对象,调用值栈对象里面的set方法(存入HashMap中)
valueStack.set(String key,Object value);
* 方式二: 获取值栈对象,调用值栈对象里面的push方法(存入数组top中)
valueStack.push(Object obj);
* 方式三: 在action成员变量位置定义变量,生成这个变量的getter方法(存入Action类中,推荐)
区别: 调用值栈对象的set()/push()方法,会将数据压栈到值栈对象中,而定义成员变量的方法,只是将对Action类进行修改
7.从值栈中获取数据
在jsp页面中,通过struts标签+ognl表达式获取值
7.1 获取Action类中成员变量属性值
private String name;
private User user;
private List<User> list;
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="name"></s:property>
<s:property value="user.username"></s:property>
<s:property value="list[0].username"></s:property>
* 遍历List集合方式一:
<s:iterator value="list">
<!--遍历list集合中的user对象-->
<s:property value="username"></s:property>
<s:property value="password"></s:property>
</s:iterator>
* 遍历List集合方式二:
<s:iterator value="list" var="user">
<!--如果定义变量来保存集合中遍历出的每一个元素的值,struts2会将原本存放在root中的数据遍历出来的
元素,临时存放在context中,因此取值需要加一个'#',表示从context中取值-->
<s:property value="#user.username"></s:property>
<s:property value="#user.password"></s:property>
</s:iterator>
7.2 获取set()/push()方法存储值栈的值
valueStack.set("hello","world...");
valueStack.push("helloTest1...");
valueStack.push("helloTest2...");
<s:property value="hello"></s:property> <!--world...-->
<!--使用push方法,struts2会将这些值放到一个叫做'top'的数组中,并遵循压栈后进先出的原则-->
<s:property value="[0].top"></s:property> <!--helloTest2......-->
<s:property value="[1].top"></s:property> <!--helloTest1......-->
7.3 使用el表达式获取值栈中的值
原理:struts2的核心过滤器(StrutsPrepareAndExecuteFilter)在执行doFilter方法时,struts会先从Request域中获取数据,如果没有再从值栈中获取数据,代码在:StrutsRequestWrapper类中getAttribute()方法
8.OGNL表达式的"#"和"%"
"#"表示从context中获取值
request.setAttribute("name","张三");
<s:property value="#request.name"/>
"%{}"表示让struts提供的表单标签,执行OGNL表达式
<s:textfield value="%{#request.name}"/> <!--效果如:<input type="text" value='张三'>-->
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190105165108539.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNTE0MTI5,size_16,color_FFFFFF,t_70)