OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。                -------百度百科

从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 ,它旨在提供一个更高抽象度语法来对 java 对象图进行导航。另外,java 中很多可以做的事情,也可以使用 OGNL 来完成,例如:列表映射和选择。对于开发者来说,使用 OGNL,可以用简洁的语法来完成对 java 对象的导航。通常来说:通过一个“路径”来完成对象信息的导航,这个“路径”可以是到 java bean 的某个属性,或者集合中的某个索引的对象,等等,而不是直接使用 get 或者 set 方法来完成。

首先来介绍下OGNL的三要素

  一、表达式:

    表达式(Expression)是整个OGNL的核心内容,所有的OGNL操作都是针对表达式解析后进行的。通过表达式来告诉OGNL操作到底要干些什么。因此,表达式其实是一个带有语法含义的字符串,整个字符串将规定操作的类型和内容。OGNL表达式支持大量的表达式,如“链式访问对象”、表达式计算、甚至还支持Lambda表达式。

  二、Root对象:

    OGNL的Root对象可以理解为OGNL的操作对象。当我们指定了一个表达式的时候,我们需要指定这个表达式针对的是哪个具体的对象。而这个具体的对象就是Root对象,这就意味着,如果有一个OGNL表达式,那么我们需要针对Root对象来进行OGNL表达式的计算并且返回结果。

  三、上下文环境:

    有个Root对象和表达式,我们就可以使用OGNL进行简单的操作了,如对Root对象的赋值与取值操作。但是,实际上在OGNL的内部,所有的操作都会在一个特定的数据环境中运行。这个数据环境就是上下文环境(Context)。OGNL的上下文环境是一个Map结构,称之为OgnlContext。Root对象也会被添加到上下文环境当中去。

OGNL 的基本语法

2.1 对Root对象的访问

  OGNL使用的是一种链式的风格进行对象的访问。具体代码如下:

  1. @Test
  2. public void testOgnl()
  3. {
  4. User user = new User("rcx", "123");
  5. Address address = new Address("110003", "沈阳市和平区");
  6. user.setAddress(address);
  7. try
  8. {
  9. System.out.println(Ognl.getValue("name", user));
  10. System.out.println(Ognl.getValue("address", user));
  11. System.out.println(Ognl.getValue("address.port", user));
  12.  
  13. //输出结果:
  14. //rcx
  15. //com.rcx.ognl.Address@dda25b
  16. //
  17. }
  18. catch (OgnlException e)
  19. {
  20. e.printStackTrace();
  21. }
  22. }

2.2 对上下文对象的访问

  使用OGNL的时候如果不设置上下文对象,系统会自动创建一个上下文对象,如果传入的参数当中包含了上下文对象则会使用传入的上下文对象。当访问上下文环境当中的参数时候,需要在表达式前面加上'#',表示了与访问Root对象的区别。具体代码如下:

  1. @Test
  2. public void testOgnl1()
  3. {
  4. User user = new User("rcx", "123");
  5. Address address = new Address("110003", "沈阳市和平区");
  6. user.setAddress(address);
  7. Map<String, Object> context = new HashMap<String, Object>();
  8. context.put("init", "hello");
  9. context.put("user", user);
  10. try
  11. {
  12. System.out.println(Ognl.getValue("#init", context, user));
  13. System.out.println(Ognl.getValue("#user.name", context, user));
  14. System.out.println(Ognl.getValue("name", context, user));
  15. //输出结果:
  16. //hello
  17. //rcx
  18. //rcx
  19. }
  20. catch (OgnlException e)
  21. {
  22. e.printStackTrace();
  23. }
  24. }

这段代码很好的区分了访问Root对象和访问上下文对象的区别。

2.3 对静态变量的访问

  在OGNL表达式当中也可以访问静态变量或者调用静态方法,格式如@[class]@[field/method()]。具体代码如下:

  1. public class Constant
  2. {
  3. public final static String ONE = "one";
  4.  
  5. public static void get()
  6. {}
  7.  
  8. public static String getString()
  9. {
  10. return "string";
  11. }
  12. }
  13.  
  14. @Test
  15. public void testOgnl2()
  16. {
  17. try
  18. {
  19. Object object = Ognl.getValue("@com.rcx.ognl.Constant@ONE", null);
  20.  
  21. Object object1 = Ognl.getValue("@com.rcx.ognl.Constant@get()", null);
  22.  
  23. Object object2 = Ognl.getValue("@com.rcx.ognl.Constant@getString()", null);
  24.  
  25. System.out.println(object);
  26. System.out.println(object1);
  27. System.out.println(object2);
  28. //one
  29. //null 当返回值是void的时候输出的是null
  30. //string
  31. }
  32. catch (OgnlException e)
  33. {
  34. e.printStackTrace();
  35. }
  36. }

2.4 方法的调用

  如果需要调用Root对象或者上下文对象当中的方法也可以使用.+方法的方式来调用。甚至可以传入参数。代码如下:

  1. @Test
  2. public void testOgnl3()
  3. {
  4. User user = new User();
  5. Map<String, Object> context = new HashMap<String, Object>();
  6. context.put("name", "rcx");
  7. context.put("password", "password");
  8. try
  9. {
  10. System.out.println(Ognl.getValue("getName()", context, user));
  11. Ognl.getValue("setName(#name)", context, user);
  12. System.out.println(Ognl.getValue("getName()", context, user));
  13. //输出结果
  14. //null
  15. //rcx
  16. }
  17. catch (OgnlException e)
  18. {
  19. e.printStackTrace();
  20. }
  21. }

从代码可以看出来,赋值的时候可以选择上下文当中的元素进行给Root对象的name属性赋值。

2.5 对数组和集合的访问

  OGNL支持对数组按照数组下标的顺序进行访问。此方式也适用于对集合的访问,对于Map支持使用键进行访问。代码如下:

  1. @Test
  2. public void testOgnl4()
  3. {
  4. User user = new User();
  5. Map<String, Object> context = new HashMap<String, Object>();
  6. String[] strings = {"aa", "bb"};
  7. ArrayList<String> list = new ArrayList<String>();
  8. list.add("aa");
  9. list.add("bb");
  10. Map<String, String> map = new HashMap<String, String>();
  11. map.put("key1", "value1");
  12. map.put("key2", "value2");
  13. context.put("list", list);
  14. context.put("strings", strings);
  15. context.put("map", map);
  16. try
  17. {
  18. System.out.println(Ognl.getValue("#strings[0]", context, user));
  19. System.out.println(Ognl.getValue("#list[0]", context, user));
  20. System.out.println(Ognl.getValue("#list[0 + 1]", context, user));
  21. System.out.println(Ognl.getValue("#map['key1']", context, user));
  22. System.out.println(Ognl.getValue("#map['key' + '2']", context, user));
  23. //输出如下:
  24. //aa
  25. //aa
  26. //bb
  27. //value1
  28. //value2
  29. }
  30. catch (OgnlException e)
  31. {
  32. e.printStackTrace();
  33. }
  34. }

从上面代码不仅看到了访问数组与集合的方式同时也可以看出来OGNL表达式当中支持操作符的简单运算。有如下所示:

  2 + 4 //整数相加(同时也支持减法、乘法、除法、取余[ % / mod]、)

  "hell" + "lo" //字符串相加

  i++ //递增、递减

  i == j //判断

  var in list //是否在容器当中

2.6 投影与选择

  OGNL支持类似数据库当中的选择与投影功能。

  投影:选出集合当中的相同属性组合成一个新的集合。语法为collection.{XXX},XXX就是集合中每个元素的公共属性。

  选择:选择就是选择出集合当中符合条件的元素组合成新的集合。语法为collection.{Y XXX},其中Y是一个选择操作符,XXX是选择用的逻辑表达式。

    选择操作符有3种:

      ? :选择满足条件的所有元素

      ^:选择满足条件的第一个元素

      $:选择满足条件的最后一个元素

   示例代码如下:

  1. @Test
  2. public void testOgnl5()
  3. {
  4. Person p1 = new Person(1, "name1");
  5. Person p2 = new Person(2, "name2");
  6. Person p3 = new Person(3, "name3");
  7. Person p4 = new Person(4, "name4");
  8. Map<String, Object> context = new HashMap<String, Object>();
  9. ArrayList<Person> list = new ArrayList<Person>();
  10. list.add(p1);
  11. list.add(p2);
  12. list.add(p3);
  13. list.add(p4);
  14. context.put("list", list);
  15. try
  16. {
  17. ArrayList<Integer> list2 = (ArrayList<Integer>) Ognl.getValue("#list.{id}", context,
  18. list);
  19. ArrayList<String> list3 = (ArrayList<String>) Ognl.getValue("#list.{id + '-' + name}",
  20. context, list);
  21. ArrayList<Person> list4 = (ArrayList<Person>) Ognl.getValue("#list.{? #this.id > 2}",
  22. context, list);
  23. ArrayList<Person> list5 = (ArrayList<Person>) Ognl.getValue("#list.{^ #this.id > 2}",
  24. context, list);
  25. ArrayList<Person> list6 = (ArrayList<Person>) Ognl.getValue("#list.{$ #this.id > 2}",
  26. context, list);
  27. System.out.println(list2);
  28. System.out.println(list3);
  29. System.out.println(list4);
  30. System.out.println(list5);
  31. System.out.println(list6);
  32. //[1, 2, 3, 4]
  33. //[1-name1, 2-name2, 3-name3, 4-name4]
  34. //[Person [id=3, name=name3], Person [id=4, name=name4]]
  35. //[Person [id=3, name=name3]]
  36. //[Person [id=4, name=name4]]
  37. //
  38. }
  39. catch (OgnlException e)
  40. {
  41. e.printStackTrace();
  42. }
  43. }

2.7 创建对象

  OGNL支持直接使用表达式来创建对象。主要有三种情况:

  构造List对象:使用{},中间使用','进行分割如{"aa", "bb", "cc"}

  构造Map对象:使用#{},中间使用',进行分割键值对,键值对使用':'区分,如#{"key1" : "value1", "key2" : "value2"}

  构造任意对象:直接使用已知的对象的构造方法进行构造。

  示例代码如下:

  1. @Test
  2. public void testOgnl6()
  3. {
  4. try
  5. {
  6. Map<String, String> map = (Map<String, String>)Ognl.getValue("#{'key1':'value1'}", null);
  7. System.out.println(map);
  8. List<String> list = (List<String>)Ognl.getValue("{'key1','value1'}", null);
  9. System.out.println(list);
  10. Object object = Ognl.getValue("new java.lang.Object()", null);
  11. System.out.println(object);
  12. //{key1=value1}
  13. //[key1, value1]
  14. //java.lang.Object@dda25b
  15. }
  16. catch (OgnlException e)
  17. {
  18. e.printStackTrace();
  19. }
  20. }

这篇OGNL的介绍就到这里,本文并没有把OGNL的所有内容都介绍出来,主要介绍了OGNL的一些简单的知识,后面有时间的话我会陆续介绍OGNL的相关知识,并且结合Struts2深入分析下OGNL的构成。同样谢谢大家的阅读,本人写博文的时候难免有错误的地方,如果大家发现希望大家给予指正,谢谢。

(转)OGNL表达式介绍的更多相关文章

  1. OGNL表达式介绍

    OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存 ...

  2. [JavaWeb基础] 029.OGNL表达式介绍

    1.OGNL概述 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对 ...

  3. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  4. JSTL标签,EL表达式,OGNL表达式,struts2标签 汇总

    一下纯属个人总结摘抄,总结一起方便查看,解决疑问,有遗漏或错误,还请指出.       1,JSTL标签总结: a).JSTL标签有什么用?          JSTL是由JCP(Java Commu ...

  5. Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作用

    我之前虽然会用,但是一直分不清彼此之间有什么区别,所以查找资料,将它们进行整合区分,加深了解, 一 介绍 1.Struts2的作用   Struts2标签库提供了主题.模板支持,极大地简化了视图页面的 ...

  6. 初窥struts2(二)OGNL表达式

    Struts2总结 Struts2完整的处理流程: 1  客户端发送请求,交给struts2控制器(StrutsPrepareAndExecuteFilter). 2  Filter控制器进行请求过滤 ...

  7. Struts2之OGNL表达式

    OGNL(Object-Graph Navigation Language的简称),对象图导航语言,它是一门表达式语言,除了用来设置和获取Java对象的属性之外,另外提供诸如集合的投影和过滤以及lam ...

  8. struts2 页面标签或ognl表达式取值--未完待续

    一.加#号取值和不加#号取值的解说 1.s:property 标签——value属性使用事项 1)涉及问题:取值时什么时候该加#,什么时候不加? 2)介绍 <s:property value=& ...

  9. OGNL表达式的基本语法和用法

    首先我们一起来看一下OGNL中的#.%和$符号. 关于OGNL各种用法总结参看:http://blog.163.com/seara520@126/blog/static/720693042010320 ...

随机推荐

  1. 最全面的Java字节byte操作,处理Java基本数据的转换及进制转换操作工具,流媒体及java底层开发项目常用工具类

    前言:用于处理Java基本数据的转换及进制转换操作工具 一.实现功能 1.int与byte互转 2.int与byte[]互转 3.short与byte互转 4.short与byte[]互转 5.16位 ...

  2. 使用外部容器运行spring-boot项目:不使用spring-boot内置容器让spring-boot项目运行在外部tomcat容器中

    前言:本项目基于maven构建 spring-boot项目可以快速构建web应用,其内置的tomcat容器也十分方便我们的测试运行: spring-boot项目需要部署在外部容器中的时候,spring ...

  3. 9个常用iptables配置实例

    iptables命令可用于配置Linux的包过滤规则,常用于实现防火墙.NAT.咋一看iptables的配置很复杂,掌握规律后,其实用iptables完成指定任务并不难,下面我们通过具体实例,学习ip ...

  4. 提高java编程质量 - (三)三目运算符的两个操作数类型尽量一致

    先看一个例子: package com.test; public class TernaryOperator { public static void main(String[] args) { in ...

  5. python基础之数据类型/字符串/元组/列表/字典

    Python 数据类型 数字类型: int整型,long 长整型(在python3.0里不区分整型和长整型).float浮点型:complex复数(python中存在小数字池:-5--257):布尔值 ...

  6. 选课 树形DP+多叉树转二叉树+dfs求解答案

    问题 A: 选课 时间限制: 1 Sec  内存限制: 128 MB 题目描述 大 学里实行学分.每门课程都有一定的学分,学生只要选修了这门课并考核通过就能获得相应的学分.学生最后的学分是他选修的各门 ...

  7. MySQL,Oracle,PostgreSQL 数据库web维护客户端管理工具

    TreeDMS数据库管理系统使用JAVA开发,采用稳定通用的springMVC +JDBC架构,实现基于WEB方式对 MySQL,Oracle,PostgreSQL 等数据库进行维护管理操作. 功能包 ...

  8. docker私有库搭建过程(Registry)

    实验环境: CentOS7 1611 Docker 1.12.6 registry   2.0 1.安装并运行registry 安装: [root@docker01 ~]# docker pull r ...

  9. java中String与StringBuffer拼接的区别

    学习笔记: 1.String拼接会创建一个新的String对象,存储拼接后的字符串: StringBuffer拼接是直接在本身拼接,会即时刷新. 2.String只能拼接String类型的字符串: S ...

  10. 数据的ID名生成新的引用索引树

    <?php $arr= [ '0'=>[ "id"=>2, "name"=>"建材", "pid" ...