什么是OGNL表达式?

OGNL是Object Graphic Navigation Language 是操作对象属性的开源表达式。 Struts2框架使用OGNL作为默认的表达式语言。

为什么我们学习OGNL

在学习JSP的时候,我们已经学习过了EL表达式。EL表达式用起来也十分简单…我们在Struts2框架中也是可以使用EL表达式的…那么OGNL表达式好在哪里呢??

  • 支持对象方法调用,如xxx.doSomeSpecial()
  • 支持类静态的方法调用和值访问,表达式的格式【例如:”@@floor(10.9)”就是调用Math.floor()的方法了】
  • 支持赋值操作和表达式串联【这个其实EL表达式也能做】
  • 访问OGNL上下文(OGNL context)和ActionContext
  • 操作集合对象【EL只能遍历集合,OGNL可以创建集合】

OGNL是Struts2的默认表达式语言,OGNL是配搭Strut2的标签使用的..我们学习了OGNL表达式,就可以更好地理解Struts2标签的运行以及Struts2内部的存储结构.

valueStack对象

在讲解OGNL表达式之前,我们先来看看valueStack对象…valueStack是Struts2数据存储的核心…我们首先要知道数据是怎么存的,存到哪里,然后才讲解OGNL表达式是怎么取出数据的

valueStack也被称作值栈对象..

  • 当用户访问Action,都会创建一个Action对象,ActionContext对象、valueStack对象..
  • Struts2把Action对象放进valueStack对象之中
  • 将valueStack放进request域中,传入JSP页面(key: struts.valueStack)
  • JSP页面就可以使用OGNL表达式获取值栈中的数据了

获取valueStack对象

  • 在Action中我们可以手动获取值栈对象,有两种方式获取
  1. //获取值栈对象的2种方式
  2. private void getVs() {
  3. // 获取值栈对象,方式1:
  4. HttpServletRequest request = ServletActionContext.getRequest();
  5. ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");
  6. // 获取值栈对象,方式2:
  7. ActionContext ac = ActionContext.getContext();
  8. ValueStack vs2 = ac.getValueStack();
  9. System.out.println(vs1 == vs2);//true
  10. }

valueStack内部存储结构

上面已经说了,用户访问Action时,会创建Action对象,valueStack对象。Struts2内部会将Action对象存到valueStack对象之中…那么valueStack的存储结构是什么样的呢???我们来看看

CompoundRoot

Action对象和Action的成员属性等值都是存到CompoundRoot下的.该CompoundRoot继承着ArrayList,因此它是List结构的

  1. public class CompoundRoot extends ArrayList {}

OgnlContext

OgnlContext对象存储着相关的域对象:request、response、session等数据,实现Map集合,是Map结构..

为了让request、response等域对象可以存储多个值,值也是使用Map结构

  1. public class OgnlContext implements Map {}

小总结

CompoundRoot保存着这样的数据:

  • Action对象以及Action对象的成员属性数据
  • 使用ValueStack对象.push()进去的数据
  • 使用ValueStack对象.set()进去的数据
  • 其他代理对象的数据

OgnlContext保存着这样的数据:

  • 维护了CompoundRoot中所有的数据
  • request、response等域对象所有的数据

OGNL表达式取值

  • Struts2会将valueStack对象封装进request对象域中,传入JSP页面。
  • valueStack存储着OgnlContext对象。
  • OgnlContext对象维护了CompoundRoot对象的数据
  • CompoundRoot存储着Action等数据

也就是说通过OgnlContext对象可以获取大部分我们需要的数据了。

那么OGNL表达式是怎么取出OgnlContext对象中数据的呢??下面我们通过硬编码的方式来讲解

  1. /**
  2. * 1. Ognl表达式语言语言取值,取非根元素的值,必须用#号
  3. * @throws Exception
  4. */
  5. @Test
  6. public void testOgnl() throws Exception {
  7. // 创建一个Ognl上下文对象
  8. OgnlContext context = new OgnlContext();
  9. // 放入数据
  10. User user = new User();
  11. user.setId(100);
  12. user.setName("Jack");
  13. // 【往非根元素放入数据, 取值的时候表达式要用"#"】
  14. context.put("user", user);
  15. // 获取数据(map)
  16. // 先构建一个Ognl表达式, 再解析表达式
  17. Object ognl = Ognl.parseExpression("#user.name");
  18. Object value = Ognl.getValue(ognl, context, context.getRoot());
  19. System.out.println(value);
  20. }
  21. /**
  22. * 2. Ognl表达式语言语言取值,取根元素的值,不用带#号
  23. * @throws Exception
  24. */
  25. @Test
  26. public void testOgn2() throws Exception {
  27. // 创建一个Ognl上下文对象
  28. OgnlContext context = new OgnlContext();
  29. // 放入数据
  30. User user = new User();
  31. user.setId(100);
  32. user.setName("Jack");
  33. // 【往根元素放入数据】
  34. context.setRoot(user);
  35. // 获取数据(map)
  36. // 先构建一个Ognl表达式, 再解析表达式
  37. Object ognl = Ognl.parseExpression("address.province");
  38. Object value = Ognl.getValue(ognl, context, context.getRoot());
  39. System.out.println(value);
  40. }

也就是说,JSP页面中取出数据的时候,它会先构建一个OGNL表达式,再解析表达式

  • 如果是CompoundRoot类的数据,表达式不需要带#号
  • 如果不是CompoundRoot类的数据,表达式需要带#号

例子:

  1. <!-- 页面: 必须要拿到ValueStack -->
  2. <br/>1. 取根元素的值<br/>
  3. <s:property value="user.id"/>
  4. <s:property value="user.name"/>
  5. <s:property value="user.address"/>
  6. <s:property value="user.address.city"/>
  7. <s:property value="user.address.province"/>
  8. <br/>2. 取非根元素的值<br/>
  9. <s:property value="#request.cn"/>
  10. <s:property value="#session.Session_data"/>
  11. <s:property value="#application.Application_data"/> <br/>
  12. <!-- 自动找request/session/application,找到后立刻返回 -->
  13. <s:property value="#request_data"/>
  14. <s:property value="#attr.Session_data"/>
  15. <s:property value="#attr.Application_data"/> <br/>
  16. <!-- 获取请求的参数数据 -->
  17. <s:property value="#parameters.userName"/>
  18. <!-- struts的调试标签:可以观测值栈数据 -->
  19. <s:debug></s:debug>

OGNL对静态方法的调用


  1. /**
  2. * 3.Ognl对 静态方法调用的支持
  3. * @throws Exception
  4. */
  5. @Test
  6. public void testOgn3() throws Exception {
  7. // 创建一个Ognl上下文对象
  8. OgnlContext context = new OgnlContext();
  9. // Ognl表单式语言,调用类的静态方法
  10. //Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
  11. // 由于Math类在开发中比较常用,所以也可以这样写
  12. Object ognl = Ognl.parseExpression("@@floor(10.9)");
  13. Object value = Ognl.getValue(ognl, context, context.getRoot());
  14. System.out.println(value);
  15. }

OGNL创建集合


  1. <br/>一、.构建 list集合</br>
  2. <s:iterator var="str" value="{'a','b'}">
  3. <s:property value="#str"/>
  4. </s:iterator>
  5. <br/>一、.构建 map集合</br>
  6. <s:iterator var="en" value="#{'cn':'China','usa':'America'}">
  7. <s:property value="#en.key"/>
  8. <s:property value="#en.value"/> <br/>
  9. </s:iterator>

构建Map集合的时候,需要使用#号


OGNL 几个特殊的符号

#获取非根元素值 、 动态都建map集合

$ 在配置文件取值

% 提供一个ognl表达式运行环境


  1. <body>
  2. <br/>获取request域数据<br/>
  3. <!-- property 标签是对象类型的标签,默认支持ognl表达式, 会从根元素去China名称对应的值 -->
  4. <s:property value="China"/> <br/>
  5. <!-- 如果直接赋值,需要用单引号 -->
  6. <s:property value="'China'"/> <br/>
  7. <s:property value="%{#request.cn}"/> <br/>
  8. <!-- 值类型的标签,value值默认就是值类型,不支持ognl表达式 -->
  9. 国家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield>
  10. </body>

Struts2第九篇【OGNL、valueStack详解】的更多相关文章

  1. (第九篇)Iptables详解

    常见的网络攻击形式 1.拒绝服务攻击:DOS 2.分布式拒绝服务攻击 DDOS 3.漏洞入侵 4.口令猜测 以上内容简单了解,具体可自行百度,此处不必知晓. Linux防火墙基础 Linux防火墙体系 ...

  2. Struts2拦截器的使用 (详解)

    Struts2拦截器的使用 (详解) 如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈default ...

  3. mysql基础篇 - SELECT 语句详解

    基础篇 - SELECT 语句详解         SELECT语句详解 一.实验简介 SQL 中最常用的 SELECT 语句,用来在表中选取数据,本节实验中将通过一系列的动手操作详细学习 SELEC ...

  4. 入木三分学网络第一篇--VRRP协议详解第一篇(转)

    因为keepalived使用了VRRP协议,所有有必要熟悉一下. 虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP)是解决局域网中配置静态网关时,静 ...

  5. Struts2 OGNL使用详解(转)

    OGNL OGNL ( Object Graph Navigation Language ),对象图导航语言.这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性. 在 Struts2 中,O ...

  6. Struts2的OGNL标签详解

    一.Struts2可以将所有标签分成3类: UI标签:主要用于生成HTML元素的标签. 非UI标签:主要用于数据库访问,逻辑控制等标签. Ajax标签:用于Ajax支持的标签. 对于UI标签,则有可以 ...

  7. Struts2中 Result类型配置详解

    一个result代表了一个可能的输出.当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出.在com.opensymphony.xwor ...

  8. Struts2学习笔记(二)——配置详解

    1.Struts2配置文件加载顺序: default.properties(默认常量配置) struts-default.xml(默认配置文件,主要配置bean和拦截器) struts-plugin. ...

  9. 实时通讯系列目录篇之SignalR详解

    一. 简单说几句 最早使用SignalR的时候大约是两年前了,记得当时是一个OA中消息的实时提醒,轮询的方式有点耗资源,WebSocket写起来又比较麻烦,最终选择了SignalR,当时是什么版本已经 ...

随机推荐

  1. XtraBackup应用说明(支持TokuDB)

    背景: 关于物理备份工具xtrabackup的一些说明可以先看之前写过的文章说明:XtraBackup 安装使用和xtrabackup 使用说明(续),本篇文章将介绍xtrabackup在使用中的注意 ...

  2. 项目记事【SpringMVC-1】:后台接收前端传来的JSON,并转成对象

    背景: 最近项目中使用SpringMVC,需要从前端接收JSON格式的请求,在后端自动转成一个与JSON格式相同的对象. 由于是一个老项目,Spring的版本是3.2.7. 问题1:POST or G ...

  3. 使用angular4搭建博客(一)

    本文长期更新,未经运行,严禁转载. 博客(制作中) http://101.200.58.228/ Github https://github.com/Teloi/TEIndex 框架选择 Angula ...

  4. Eclipse自动生成返回值对象的快捷键是什么?

    如下代码 List<ShareholderEntity> shareList = fetch.parseShareHolder(data); 如何自动生成 List<Sharehol ...

  5. Windows常用的一些DOS下的CMD命令整理

    Windows常用的一些DOS下的CMD命令整理... -------------- 正斜杠--/////-----向右倒--网址正斜杠反斜杠--\\\\------向左倒--文件路径反斜杠 DOS命 ...

  6. 【Linux】CentOS7无法使用tab补全功能

    公司新项目在云环境上用CentOS7搭服务器的时候,遇见了无法Tab键自动补齐的情况,上网搜了一下,是因为Centos7在使用最小化安装的时候,没有安装自动补全的包,需要自己手动安装. yum ins ...

  7. Java初学者必知 关于Java字符串问题

    摘自 http://developer.51cto.com/art/201503/469443.htm 下面我为大家总结了10条Java开发者经常会提的关于Java字符串的问题,如果你也是Java初学 ...

  8. java线程锁

    一.synchronized         这货可以锁对象,锁变量,锁方法,锁代码,好像什么都能锁,缺点就是如果一个锁堵了,其他的只能等待忙并不能把当前的锁给释放.二. ReentrantLockR ...

  9. informatica9 安装下载,安装教程 介质(文章和视频教程)(csdn讲师:Array)

    Informatica学习:  参考文献:视频参考地址:http://edu.csdn.net/course/detail/5034,ETL之informatica9通关班(第二期) 1.安装介质的获 ...

  10. 给你的网站免费配置上 HTTPS 证书

    现在越来越多的网站或服务增加了 HTTPS 证书,苹果 AppStore.微信小程序等也已强制要求开发者需提供 HTTPS 的后端接口.在阿里云 / 腾讯云上有一年期的免费赛门铁克 SSL 证书可供尝 ...