值栈的概念和作用是什么?
值栈(ValueStack)就是OGNL表达式存取数据的地方。在一个值栈中,封装了一次请求所需要的所有数据。在使用Struts2的项目中,Struts2会为每个请求创建一个新的值栈,也就是说,值栈和请求是一一对应的关系,这种一一对应的关系使值栈能够线程安全地为每个请求提供公共的数据存取服务。
1.值栈的作用
值栈可以作为一个数据中转站在前台与后台之间传递数据,最常见的就是将Struts2的标签与OGNL表达式结合使用。值栈实际上是一个接口,在Struts2中利用OGNL时,实际上使用的就是实现了该接口的OgnlValueStack类,这个类是OGNL基础。
2.值栈的生命周期
值栈贯穿整个Action的生命周期,每个Action类的对象实例都拥有一个ValueStack对象,在ValueStack对象中保存了当前Action对象和其他相关对象。Struts2框架把ValueStack对象保存在一个名为struts.valueStack的request属性中,也就是说,值栈与Action的生命周期一致。值栈的生命周期随着request的创建而创建,随着request的销毁而销毁。
3.值栈的获取方式
要获取值栈中存储的数据,首先应该获取值栈。值栈的获取有两种方式,具体如下。
(1)在request中获取值栈
ValueStack对象在request范围内的存储方式为request.setAttribute(“struts.valueStack”,valuestack),可以通过如下方式从request中取出值栈的信息。
//获取ValueStack对象,通过request对象获取
ValueStack valueStack=(ValueStack)ServletActionContext.getRequest()
.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
在上述示例代码中,ServletActionContext.STRUTS_VALUESTACK_KEY是ServletActionContext类中的常量,它的值为struts.valueStack。
(2)在ActionContext中获取值栈
在使用Struts2框架时,可以使用OGNL操作Context对象从ValueStack中存取数据,也就是说,可以从Context对象中获取ValueStack对象。实际上,Struts2框架中的Context对象就是ActionContext。ActionContext获取ValueStack对象的方式如下所示:
//通过ActionContext获取valueStack对象
ValueStack valueStack=ActionContext.getContext().getValueStack();
ActionContext对象是在StrutsPrepareAndFilter的doFilter()方法中被创建的,在源码中用于创建ActionContext对象的createActionContext()方法内可以找到获取的ValueStack对象的信息,方法中还有这样一段代码:ctx=new ActionContext(stack.getContext()),从代码中可以看出,ValueStack对象中的Context对象被作为参数传递给了ActionContext对象,这也就说明ActionContext对象中持有了ValueStack对象的引用,因此可以通过ActionContext对象获取ValueStack对象。