一、什么是Ognl?

      通过百度百科查询到的解释,其中详细的说明了OGNL的作用。

          

      下面我们就对OGNL这5个作用进行讲解

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

      2、调用对象方法。

      3、调用类的静态方法

      4、索引数组元素

      5、操作集合(重 要)

二、OGNL的功能实现

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

         Ognl.getValue(expression,context,root);

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

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

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

      2.1、对javabean进行操作

        User.java

            

        Address.java

            

        获取javabean中的属性值

            

        获取javabean中的对象的属性值

                

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

            

         

      2.2、调用对象方法

             

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

            

        

       2.4、索引数组元素

            

       2.5、操作集合

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

                  

            操作map集合

                  

            创建list集合

                  

            创建map集合

                  

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

            

三、OGNL与struts2的结合

      上面说了那么一大堆的OGNL的使用功能,我们也感受到了他的强大,啥都能取出来,表达式啥都能做,但是在struts2中它是如何使用的呢?

      OGNL中的上下文即struts2中的actionContext

      OGNL中的root即struts2中的valueStack

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

      3.1、ActionContext和valueStack(重要)

          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域中查找也能够获取到。

            

       

   

          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.2、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();

     3.3、struts2不同的地方使用OGNL表达式获取数据

          3.3.4、在jsp页面中

             大部分都会在这里使用,因为jsp就是显示数据的地方,在struts2中有很多s标签,通过s标签和OGNL表达式一起配置使用,就能拿到想要的数据了。而OGNL的表达式的编写在最开始就已经讲解过了,context就是actionContext,root就是valueStack,剩下表达式就看我们需要什么了。标签的讲解会在下一章

          3.3.5、在struts.xml中

             在struts.xml中有时候也需要用到OGNL表达式去拿一些数据。比如,在result中设置stream时,就需要从action中获取流,而action可以看成是javabean,又在栈顶,所以直接使用OGNL表达式就能够获取到,但是注意特殊的,如果在你直接编写ognl表达式时struts2不能够区分出这是ognl表达式还是普通文本,那么就需要使用${}来表明该段文本是ognl表达式

              

四、总结

      struts2我觉得最重要的两点,

            一、理解它的架构图,知道大概的流程,

            二、该篇文章讲解的值栈,actionContext,ognl的关系,

      这两个弄懂了,基本上没什么难得倒我们了,在写三到四篇文章就可以把struts2给结束掉,还差的知识点有,s标签的使用、国际化、还有文件上传和下载的功能详细讲解,最后通过小项目将struts使用起来,就完了。

Struts2学习(四)———— ognl表达式、值栈、actionContext之间的关系的更多相关文章

  1. struts2中,OGNL访问值栈的时候查找的顺序是什么?请排序:模型对象、临时对象、固定名称的对象、Action对象

    struts2中,OGNL访问值栈的时候查找的顺序是什么?请排序:模型对象.临时对象.固定名称的对象.Action对象 解答:struts2的值栈排列顺序为:1).临时对象:2).模型对象:3).Ac ...

  2. Struts2学习记录-Value Stack(值栈)和OGNL表达式

    仅仅是学习记录.把我知道的都说出来 一.值栈的作用 记录处理当前请求的action的数据. 二,小样例 有两个action:Action1和Action2 Action1有两个属性:name和pass ...

  3. struts2学习笔记--OGNL表达式1

    struts2标签库主要使用的是OGNL语言,类似于El表达式,但是强大得多,它是一种操作对象属性的表达式语言,OGNL有自己的优点: 能够访问对象的方法,如list.size(); 能够访问静态属性 ...

  4. 框架学习之Struts2(三)---OGNL和值栈

    一.OGNL概述 1.1OGNL是对象图导航语言(Object-Graph Navigation Languaged)的缩写,他是一种功能强大的表达式语言,通过简单一致的表达式语法,可以存取Java对 ...

  5. 【基于初学者的SSH】struts2 值栈的详解与struts2标签库+ognl表达式

    一:什么是值栈:struts2里面本身提供的一种存储机制,类似于域对象,值栈,可以存值和取值 特点:先进后出,最上面的元素叫做栈顶,也叫压栈. <s:debug></s:debug& ...

  6. Struts2笔记3--获取ServletAPI和OGNL与值栈

    获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.getConte ...

  7. (转)OGNL与值栈

    http://blog.csdn.net/yerenyuan_pku/article/details/67709693 OGNL的概述 什么是OGNL 据度娘所说: OGNL是Object-Graph ...

  8. (补充)9.Struts2中的OGNL表达式

    OGNL表达式概述 1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写 * 所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关 ...

  9. [转] valuestack,stackContext,ActionContext.之间的关系

    三者之间的关系如下图所示: ActionContext  一次Action调用都会创建一个ActionContext  调用:ActionContext context = ActionContext ...

  10. valuestack,stackContext,ActionContext.之间的关系

    者之间的关系如下图所示: relation ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionC ...

随机推荐

  1. ping内网一台虚拟机延时很大(hyper-v虚拟机)的解决办法

    问题现象: ping 内网一台虚拟机延时很大,不稳定,造成业务系统响应慢.查看服务器上各种资源都正常. 解决办法: 在物理机上找到和hyper-v绑定的那个网卡,把“虚拟机队列”禁用掉就好了,如下图: ...

  2. 【并发编程】IO模型

    一.要点回顾 为了更好地了解IO模型,我们需要先回顾下几个概念:同步.异步.阻塞.非阻塞 同步: 一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行.就是在发出一个功能调用时,在没 ...

  3. BeanUtil拷贝

    拷贝vo对象 一些查询到的数据很多是不需要的,可以创建vo对象,对需要的对象属性进行拷贝 maven依赖 <dependency> <groupId>org.projectlo ...

  4. vs.code调试node.js的C++扩展

    其实也很简单 点击“Add Configration..”后,会在launch.json增加一个节点,稍调整两个位置 以上完了后,就能在cpp源码里加上自己的断点,执行debug调试我们的C++源代码 ...

  5. 消息中间件——RabbitMQ

    RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.RabbitM ...

  6. Delphi控件cxGrid 如何动态创建列?

    方法一: var i: Integer; Column: TcxGridDBColumn; cxView: TcxGridDBTableView; begin cxView := Self.Level ...

  7. 理解Time-Wait

    What is it? TIME-WAIT状态的主要作用在于TCP连接的拆除阶段.拆除一个TCP连接通常需要交换4个segment,如下图所示: Host1上的应用程序关闭了自己这一端的连接,使得TC ...

  8. Unity3d让某个物体一直正对着相机

    //将以下代码绑定到相机上 using UnityEngine; using System.Collections;   public class LookatScipt : MonoBehaviou ...

  9. MFC中的Debug Assertion Failed 如何查找原因

    编写MFC程序时经常会遇到下图所示的断言失败问题 报错对话框中给出了一个目录,是在F盘,但是查找之后会发现电脑里可能根本没有这个目录. 最后发现可以在VS的安装目录下找到这个文件: \atlmfc\s ...

  10. 踩了的Dockerfile的坑

    1.Dockerfile VOLUME的目录,RUN命令操作该目录无效 VOLUME $APP_HOME RUN mkdir -p $APP_HOME && mkdir -p $APP ...