zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    分布式锁获取token
    美团-2019Q2述职总结
    linux df 日志删除命令分析
    MySQL、HBase、ES的特点和区别
    C++函数返回局部变量
    C语言 数组初始化的三种常用方法({0}, memset, for循环赋值)以及原理
    C Mysql API连接Mysql
    C++运算符重载
    C++对象赋值的四种方式
    C/C++下scanf的%匹配以及过滤字符串问题
  • 原文地址:https://www.cnblogs.com/lyjs/p/4984685.html
Copyright © 2011-2022 走看看