struts2.1.6教程四_2、ActionContext 、ValueStack 、Stack Context

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的方式

原文地址:https://www.cnblogs.com/crazylqy/p/4428536.html