OGNL表达式语言

OGNL:Object Graphic Navigation Language(对象图导航图语言)

1、上下文------>ActionContext------>Map集合

OGNL有一个上下文概念,在Struts2中上下文的实现为ActionContext,它就是一个Map结构,它实现了java.utils.Map 接口。

OGNL COntext:

  • ValueStack(值栈,它是根对象)
  • parameters
  • request
  • session
  • application
  • attr

Action中的实例变量为什么可以被OGNL访问呢?

当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。
2、怎么访问上下文中的对象呢?

访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session.

特例:OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。

3、ValueStack(值栈)为什么特殊

根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象。

OgnlValueStack root变量[action ,Ognl util,......]

在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。

4、为何使用EL表达式能够访问valueStack中对象的属性


原因是Struts2对HttpServletRequest作了进一步的封装:

public class StrutsRequestWrapper extends HttpServletRequestWrapper {
       public StrutsRequestWrapper(HttpServletRequest req) {
           super(req);
       }
       public Object getAttribute(String s) {
        ......
        ActionContext ctx = ActionContext.getContext();
        Object attribute = super.getAttribute(s);//先从request范围获取属性值
        if (ctx != null) {
            if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
               ......
               ValueStack stack = ctx.getValueStack();
               attribute = stack.findValue(s);
               ......
            }
        }
        return attribute;
    }
 }

5、实战分析

1、访问Context中的其他对象:

 <s:property value="#request.user"/>
 <s:property value="#session.name"/>

2、采用OGNL表达式创建List、Map集合对象

List对象:

<s:set name="list" value="{'第一个','第二个','第三个'}"/>
  <s:iterator value="#list">
      <s:property/><br/>
 </s:iterator>

#list :因为list放在Context中,和访问application、request等等一样,需要使用#

<s:iterator> 标签有个特点:在迭代集合时候,会把当前迭代对象放在值栈的栈顶

<s:property>中value省略,默认从栈顶查找。

Map:

 <s:set name="maps" value="#{'key1':90,'key2':34}"/>
  <s:iterator value="#maps">
      <s:property value="key"/> = <s:property value="value"/><br/>    
  </s:iterator>

value="#{}" 比set对了一个#

 

3、判断对象是否存在于集合中

<s:if test="'foo' in {'foo','jia'}"></s:if>
      
<s:if test="'foo' not in {'ssss','jia'}">
      不在
</s:if>

 

posted @ 2015-11-21 20:50  好人难寻  阅读(252)  评论(0)    收藏  举报