struts2(六)之ognl表达式与ActionContext、ValueStack 一、OGNL表达式语言概述 二、OGNL功能实现 三、OGNL与Struts2的结合 四、struts2中使用OGNL表达式获取数据

前言

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

1.1、OGNL表达式简介

  百度上是这样说:

  struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用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

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  2)Address.java

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  3)获取javabean中的属性值

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

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

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

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

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

2.2、调用对象方法

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

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

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

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

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

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

  2)访问静态变量

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

    例如:@java.lang.Math@PI

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

    结果:

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

2.4、索引数组元素

  struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

2.5、操作集合

  1)操作list集合

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

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  2)操作map集合

    取root下的map集合中的value值

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

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

    格式:#key

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  3)创建list集合

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

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  4)创建map集合

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

    struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

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,所以其中都是以键值对的形式存储对象,如下图所示:

  struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  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,给一次请求中共享数据的功能

  struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  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的关系(重要)

  struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据

  也就是说,通过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表达式。

  struts2(六)之ognl表达式与ActionContext、ValueStack
一、OGNL表达式语言概述
二、OGNL功能实现
三、OGNL与Struts2的结合
四、struts2中使用OGNL表达式获取数据