ValueStack(值栈)
贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象. Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中
在 ValueStack 对象的内部有两个逻辑部分
1. ContextMap[Map栈]
Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中. 实际上就是对 ActionContext 的一个引用
Struts 会把下面这些映射压入 ContextMap 中
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application
ObjectStack[对象栈]
Struts 把Action 和相关对象压入ObjectStack 中
隐含request对象
在JSP页面用request对象:<%=request%>可以打印出此时的request对象,发现是org.apache.struts2.dispatcher.StrutsRequestWrapper@8b73a2。此类重写了getAttribute方法。此方法不再是直接从ServletRequest中获取属性,而是从值栈中获取。
<s:debug></s:debug>
通过加入struts2标签库<%@ taglib prefix="s" uri="/struts-tags" %>,可以用<s:debug></s:debug>来跟踪值栈动态。
使用 EL 访问值栈中对象的属性
<s:property value=“fieldName”> 也可以通过 JSP EL 来达到目的: ${fieldName}
原理: Struts2 将包装 HttpServletRequest 对象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper 对象传到页面上, 而这个类重写了 getAttribute() 方法.
源代码解读[个人理解]
request对应的类为org.apache.struts2.dispatcher.StrutsRequestWrapper,此类是HttpServletRequestWrapper的包装类,主要作用是重写getAttribute方法。在getAttribute方法中,或到值栈中获取属性。值栈对应的类是com.opensymphony.xwork2.util.ValueStack,其具体实现为com.opensymphony.xwork2.ognl.OgnlValueStack。值栈由两个主要的属性CompoundRoot root和Map<String, Object> context。其中,root用户放置请求的交互数据,包括基本类型和对象类型等。context为值栈的上下文,用于存放parameters,request,session.application等数据。