ActionContext
一次Action调用都会创建一个ActionContext
调用:ActionContext context = ActionContext.getContext()
ValueStack
由OGNL框架实现
可以把它简单的看作一个栈(List) 。
Stack Object:放入stack中的对象,一般是action。
Stack Context(map):stack上下文,它包含一系列对象,包括request/session/attr/application map等。
EL:存取对象的任意属性,调用对象的方法,遍历整个对象结…
ActionContext是Action上下文,可以得到request session application
ValueStack是值栈 存放表单中的值
Stack Context 栈上下文 也是用来存值的
struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:
|--request
|
|--application
|
context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]
|
|--session
|
|--attr
|
|--parameters
在Struts2中,采用标准命名的上下文(Context)来处理OGNL表达式。处理OGNL的顶级对象是一个Map(也叫context
map),而OGNL在这个context中就是一个顶级对象(root)。在用法上,顶级对象的属性访问,是不需要任何标记前缀的。而其它非顶级的对象
访问,需要使用#标记。
Struts2框架把OGNL Context设置为我们的ActionContext。并且ValueStack作为OGNL的根对象。除value
stack之外,Struts2框架还把代表application、session、request这些对象的Map对象也放到
ActionContext中去。(这也就是Struts2建议在Action类中不要直接访问Servlet
API的原因,他可以通过ActionContext对象来部分代替这些(Servlet API)功能,以方便对Action类进行测试!)
Action的实例,总是放到value
stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问
ActionContext中其它对象的属性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。
那么访问Action中的属性的代码就可以这样写
<s:property value="postalCode"/> 其它ActionContext中的非根对象属性的访问要像下面这样写: <s:property value="#session.mySessionPropKey"/> or <s:property value="#session[‘mySessionPropKey‘]"/> or <s:property value="#request[‘myRequestPropKey‘]"/> 对Collection的处理,内容就很简单。 <s:select label="label" name="name" list="{‘name1‘,‘name2‘,‘name3‘}" value="%{‘name2‘}" /> 这是处理List。这个代码在页面上建立一个下拉选项,内容是list中的内容,默认值是name2. 处理map <s:select label="label" name="name" list="#{‘foo‘:‘foovalue‘, ‘bar‘:‘barvalue‘}" /> 需要注意的是,判断一个值是否在collection中。我们要使用in或者not in来处理。 <s:if test="‘foo‘ in {‘foo‘,‘bar‘}"> muhahaha </s:if> <s:else> boo </s:else> 另外,可以使用通配符来选择collection对象的子集。 ?——所有匹配选择逻辑的元素 ^——只提取符合选择逻辑的第一个元素 $——只提取符合选择逻辑的最后一个元素 person.relatives.{? #this.gender == ‘male‘}
以下为补充摘录的一些问题:
1.提问:在Struts2中,如何使用自身的Tag读取Action中的变量?
Struts2
自身的Tag会根据value中的OGNL表达式,在ValueStack中寻找相应的对象。因为action在ValueStack的顶部,所以默认情
况下,Struts2的Tag中的OGNL表达式将查找action中的变量。请注意,value中的内容直接是OGNL表达式,无需任何el的标签包
装。
例如:<s:property value="user.name" />
2.提问:在Struts2中,如何使用自身的Tag读取HttpServletRequest,HttpSession中的变量?
在
上面的知识中,我们知道,Struts2中OGNL的上下文环境中,包含request,session,application等servlet对象的
Map封装。既然这些对象都在OGNL的上下文中,那么根据OGNL的基本知识,我们可以通过在表达式前面加上#符号来对这些变量的值进行访问。
例如:<s:property value="%{#application.myApplicationAttribute}" />
<s:property value="%{#session.mySessionAttribute}" />
<s:property value="%{#request.myRequestAttribute}" />
<s:property value="%{#parameters.myParameter}" />
3.通俗struts2中ValueStack和Stack Context二者的区别。
ValueStack 由 OGNL框架实现,可以把它简单的看作一个栈(List) Stack Context(保存方式是map类型):stack的上下文,它包含一系列对象,包括 request,session,attr,application,map 等ValueStack中保存的值可以直接取,而stack中的需要在前面加#(request,session,application)
一句话就是两种都可以存储值,一种struts封装建议的方式,是保留原始的servletAPI的方式