一、 定义:值栈贯穿整个action的生命周期,相当于一个数据中转站,保存着action对象和其他对象。
二、 在ValueStack对象内部有两个逻辑部分
a) ObjectStack:root属性,是一个ArrayList,包含Action对象和其他对象。
b) ContextMap:context属性,是一个Map,默认压入内容(request,session,application,attr,parameters)。
当struts2接受一个请求时,会创建一个ActionContext,ValueStack,Action实例。将action存放进ValueStack,所以action的实例变量可以被OGNL访问,OGNL表达式需要配合struts标签才可以使用。
Struts的property标签用来输出值栈中的一个属性值,如:
<s:property value="username"/>
详细流程:
1)Struts2
接收到一个action请求后,会创建action实例,但是并不会调用action方法,而是先将Action类的相应属性放到ValueStack对象的栈顶,所有的属性值都是默认值。
2)然后struts2调用拦截器链上的拦截器,其中struts2就会通过params拦截器,将ValueStack中和Action类中属性名字相同的请求参数赋值给Action类中对应的属性,
3)最后调用Action类的Action方法。
三、值栈的操作
a) 获得值栈对象
ValueStackvs1 = (ValueStack)ServletActionContext.getRequest().getAttribute("struts.valueStack");
ValueStack vs2 = (ValueStack)ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
ValueStackvs3 = ActionContext.getContext().getValueStack();
b) 向值栈保存数据
i. valueStack.push(Object obj)
ii. valueStack.set(String key ,Object obj)
二、OGNL(Object-Graph-Navigation-Language)对象导航图语言
a) 访问ObjectStack中的数据,没有#号
b) 访问ContextMap中的数据,由于它们不是根对象,需要加#号前缀
Action类中的代码:
ServletActionContext.getRequest().setAttribute("username","username_request");
ServletActionContext.getContext().getSession().put("username","username_session");
ServletActionContext.getServletContext().setAttribute("username","username_application");
ValueStack valueStack = ServletActionContext.getContext().getValueStack();
valueStack.set("username","username_valueStack");
Jsp页面中的代码:
<!-- username_request -->
request: <s:property value="#request.username"/><br>
<!-- username_session -->
session: <s:property value="#session.username"/> <br>
<!-- username_application -->
application: <s:property value="#application.username"/> <br>
<!-- username_request -->
attr: <s:property value="#attr.username"/> <br>
<!-- username_valueStack -->
valueStack: <s:property value="username"/> <br>
<!-- Lynx -->
parameters: <s:property value="#parameters.username[0]"/> <br>