zoukankan      html  css  js  c++  java
  • struts2(六)之ognl表达式与ActionContext、ValueStack

    前言

      前面已经把struts2讲内容说了一半了,我写的很详细,希望对博友们有帮助。

    一、OGNL表达式语言概述

    1.1、OGNL表达式简介

      百度上是这样说:

      

      OGNL是Object-Graph Navigation Language的缩写,它是一个单独的开源项目。Struts2框架使用OGNL作为默认的表达式语言。

      它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的

      结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。

    1.2、OGNL功能概述

      对OGNL这5个作用进行讲解:

        1)存取对象的任意属性,简单说就是对javabean进行操作(重要)

        2)调用对象方法

        3)调用类的静态方法

        4)索引数组元素

        5)操作集合(重 要)

    1.4、OGNL表达式使用格式

      操作之前必须知道如何使用OGNL表达式,并且了解OGNL表达式的取值范围只能在其context和root中,格式为:

        Ognl.getValue(expression,context,root);

             //expression:为我们编写的ognl表达式,从后两个参数中获取值,获取规则会从下面的例子中详细讲解

             //context:ognl的上下文,类型为map,

             //root:ognl的根,可以为javabean、list、map、.... 等等很多值

    二、OGNL功能实现

    2.1、对javabean进行操作

      1)User.java

        

      2)Address.java

        

      3)获取javabean中的属性值

        

      4)获取javabean中的对象的属性值

        

      5)对javabean中的属性进行赋值操作

        

    2.2、调用对象方法

        

    2.3、调用类的静态方法或属性

      这里获取静态方法和静态变量,不受方法或属性是否在root或者上下文中的限制。
      编写user对象放入root中只是为了满足使用Ognl的条件,没有别的作用。
      1)访问静态方法

        调用系统的类的静态方法,调用编写的类的静态方法,都是一样的。

        格式:@包名+类名@静态方法

        例如:@java.util.UUID@randomUUID()

      2)访问静态变量

        格式:@包名+类名@静态变量名

        例如:@java.lang.Math@PI

        

        结果:

        

    2.4、索引数组元素

      

    2.5、操作集合

      1)操作list集合

        list结合本质就是一个数组,所以从list中读取数据跟对数组的操作是一样的。

        

      2)操作map集合

        取root下的map集合中的value值

        格式:key   直接写上key,就能找到对应的value值,如果value值是一个对象,那么通过“.”来获取中的属性。

        如果想获取上下文中的属性,因为上下文就是一个map,为了区分是从root下取还是从上下文中取。使用“#”区分

        格式:#key

        

      3)创建list集合

        格式:{xxx,xxxx,xxxxx......}

        

      4)创建map集合

        格式:#{'key':'value','key':'value'}

        

    2.6、其他用法

      使用数学运算符,使用“,”号连接表达式,in与not in运算符,投影、过滤等操作就不讲解了,都非常简单,重点掌握上面的即可。

    三、OGNL与Struts2的结合

      从上面的例子中我们可以看出来OGNL的功能非常的强大,能对对象进行存取,能操作少数组、集合。那在struts2中是如何使用的呢?

      OGNL中的上下文即struts2中的actionContext

      OGNL中的root即struts2中的valueStack

      ctionContext和valueStack是什么,他们之间什么关系?

    3.1、ActionContext

      充当OGNL的context。是action的上下文,也可以叫做action的数据中心,本质是一个map,在其中,所有的数据都存放在这里,

      那其中到底存放了哪些东西呢,actionContext中存放数据的方式又是怎样的?

      actionContext是一个map,所以其中都是以键值对的形式存储对象,如下图所示:

      

      request、session、application这种我们熟知的作用域,注意是作用域,而不是对象,

      paramters:这个是表单提交的参数,全部都会放到这个map中,

      attr(attributes):三个作用域所有的属性都会放在该map下,如果有重复的,那么以request域中的为准

      VALUE_STACK:值栈,存放着valueStack对象,也就是说,通过ActionContext能够获取到valueStack

      如果我们使用actionContext.put();  那么会将该键值对直接放入到ActionContext下。

      注意:除了request外,其他都可以直接通过getXxx()获得。而想要获取request作用域,必须通过key值的方式来获取。ActionContext.getContext().get("request");  

           为什么这样呢?因为struts2对request进行了增强。从这里actionContext中是不能直接获取到的,request进行了怎样的增强呢?比如在actionContext中put了

        一个普通的key和value,该键值对并没有在request域中,但是在jsp中,通过在request域查找key,也能找到该键值对,底层进行了两步:第一步:从request域

        中查找数据,第二步:如果没有找到,将从值栈中执行findValue()。  这样就解释了为什么通过ActionContext不能直接获取request,并且为什么不在request作

        用域中的数据,而通过在request域中查找也能够获取到。

    3.2、ValueStack

      值栈,本质是一个ArrayList,作用,充当ognl的root,给一次请求中共享数据的功能

      

      root:源码中的名称为CompoundRoot,它也是一个栈,而每次值栈中入栈和出栈等操作其实就是对CompoundRoot进行对应的操作。

      Context:对actionContext的引用,也就是通过valueStack也能够获取到上下文,通过getContext();

      在我们访问一个action时,会将action加入到栈顶,也就是action会在CompoundRoot的栈顶,而我们提交的各种表单参数(充当了ognl表达式)会

      在valueStack从顶向下查找对应的属性进行赋值。这就是值栈的作用。

      值栈的操作

        这里提一下,知道了值栈的内部结构图,那么就好理解了。

        action中手动向valueStack中放数据。

          ActionContext.getContext().getValueStack().push(xxx);  //一般是javabean,这样放是放在root中,因为push操作是对栈进行操作,也就是对root进行操作

          ActionContext.getContext().getValueStack().set(key,value);  //任意值,以key-value的形式放入到了root中。

        jsp获取

          push存放,在root下,直接使用属性获取即可

          set存放,通过属性也可以直接获得。这里要排除一个误区,就是不要觉得set方式是以键值对的方式存放,就觉得是放入了context中,并没有,还是在root中锝

        context操作

          ActionContext.getContext().put(key,value);  //存放在actionContext中,也就是OGNL的context中

        JSP获取:三种方式进行获取

          #key获取。  

          直接使用key获取,因为值栈中也有context。只不过要从栈顶中的root开始找,然后在从context中查找

          #request获取。因为struts2对request进行了增强,如果request域中找不到,则使用findValue(),从值栈中的root开始一路往下找。

    3.3、ActionContext和valueStack的关系(重要)

      

      也就是说,通过valueStack可以获取到actionContext,通过ActionContext也可以获取到valueStack。  

      valueStack是对root进行操作,而actionContext是对context进行操作。(root和context是OGNL中的根和上下文)

      获取值栈的方式:

        ActionContext.getContext.getValueStack();//常用

        ActionContext.getContext.get("VALUE_STACK");

        request.getAttribute("VALUE_STACK");    //这个为什么可以?因为request进行了增强。详情看上面的解释。

      获取actionContext的方式

        ActionContext.getContext();  //常用

        valueStack.getContext();

    四、struts2中使用OGNL表达式获取数据

    4.1、jsp页面中

      大部分都会在这里使用,因为jsp就是显示数据的地方,在struts2中有很多s标签,通过s标签和OGNL表达式一起配置使用,就能拿到想要的数据了

      而OGNL的表达式的编写在最开始就已经讲解过了,context就是actionContext,root就是valueStack,剩下表达式就看我们需要什么了。

    4.2、在struts.xml中

      在struts.xml中有时候也需要用到OGNL表达式去拿一些数据。比如,在result中设置stream时,就需要从action中获取流,而action可以看成是javabean,

      又在栈顶,所以直接使用OGNL表达式就能够获取到,但是注意特殊的,如果在你直接编写ognl表达式时struts2不能够区分出这是ognl表达式还是普通文

      本,那么就需要使用${}来表明该段文本是ognl表达式。

      

  • 相关阅读:
    设计模式学习系列3 观察者模式
    设计模式学习系列2 面向对象的5大原则(转)
    设计模式学习系列1 单例模式
    又见到面试的毕业生
    猎头给我打电话
    DirectX基础学习系列8 渐进网格以及外接体
    directX基础学习系列7 网格(自己创建)
    DirectX 基础学习系列6 字体
    语艺杂谈1 – MAP赋值与插入
    DirectX基础学习系列5 融合技术
  • 原文地址:https://www.cnblogs.com/zhangyinhua/p/7779260.html
Copyright © 2011-2022 走看看