ValueStack值栈和ActionContext
Struts2在OGNL之上提供的最大附加特性就是支持值栈(ValueStack),在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟对象。
一:值栈(ValueStack)
我们可以先获得ValueStack接口对象
// 01.获取到ValueStack接口对象 ,在request请求中。 HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack");
打上断点进行调试
下面我们使用Action类分别向Value Stack和Stack Context放值:
//放到单列Value Stack User user = new User(); user.setAge(12); user.setUsername("陈坤"); vs.getRoot().add(user); //放到双列Stack Context(取值得加#) vs.getContext().put("user", user);
我们访问页面:
<h1>取单列Value Stack</h1> 姓名:<s:property value="username"/><br/> <hr/> <h1>取双列Stack Context(取值得加#)</h1> 姓名:<s:property value="#user.username"/><br/> <hr/>
结果:
我们知道OGNL中有一个标签
<s:debug></s:debug>
我们使用来监视Value Stack和Stack Context中的值变化
明显,我们在Value Stack中找到我们刚刚加入的值
同样,我们在Stack Context中也找到我们刚刚加入的值(内容太多,只截图了一部分)
总结:
1.Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext,这点在我们上面调试中的图可以明显的看出),并将值栈作为OGNL的根对象。值栈类似于正常的栈,符合后进先出的栈特点,你可以在值栈中放入,删除和查询对象,值栈是Struts2的核心。
2.值栈通过一个接口(com.opensymphony.xwork2.util.ValueStack)来定义,对应的实现类是com.opensymphony.xwork2.util.OgnlValueStack。
3.顺着值栈,框架在ActionContext中还放置其他对象,包括表示application,session和request的Map对象。这些对象共存于ActionContext中,靠在值栈(OGNL根对象)的旁边,
可以举个例子:
4.我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中其他对象则需要使用“#”来标记。由于值栈是上下文中的根对象,因此可以直接访问。那么对于值栈中的对象如何访问呢?Struts2提供了一个特殊的OGNLProperty Accessor,它可以自动查找栈内的所有对象(从栈顶到栈底),直到找到一个具有你所查的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,二不需要使用“#”。