OGNL

一.概述

以下内容摘自Ognl的官网:

  OGNL stands for Object-Graph Navigation Language; it is an expression language for getting and setting properties of Java objects, plus other extras such as list projection and selection and lambda expressions. You use the same expression for both getting and setting the value of a property.

  The Ognl class contains convenience methods for evaluating OGNL expressions. You can do this in two stages, parsing an expression into an internal form and then using that internal form to either set or get the value of a property; or you can do it in a single stage, and get or set a property using the String form of the expression directly.

OGNL的全称叫做对象图导航语言,是一个用于获取与设置Java对象的表达式语言,还附加一些例如集合投影、过滤、Lambda表达式的功能。你可以使用同一个表达式实现属性的赋值或取值。

Ognl的类中包含的很方便的方法实现OGNL表达式的赋值。实现这个功能你需要两步,解析一个表达式使之称为一种内部的形式然后再用这种内部的形式对属性赋值或取值;或者你可以实现这个功能只用一步,直接用字符串来实现属性的取值或者赋值。

二. 代码案例

2.1 定义两个JavaBean

public class Dog {
private String name;
//setter and getter
}
public class Person {
private String name;
private Dog dog;
//setter and getter
}

2.2 测试用例

2.2.1 获取属性

@Test
public void test1(){
Dog dog = new Dog();
dog.setName("wangcai"); Dog dog1 = new Dog();
dog1.setName("wangwang"); Person person = new Person();
person.setName("zhagnsan");
person.setDog(dog1); OgnlContext context = new OgnlContext(); //实例化一个Ognl的上下文
context.put("person", person);
context.put("dog", dog); context.setRoot(person); //将person设置为ongl的根
try {
//使用Ognl.paraseExpression(str)来解析ognl表达式。dog是person这个根对象的属性,可以直接写属性名
Object obj = Ognl.getValue(Ognl.parseExpression("dog.name"), context, context.getRoot());
System.out.println(obj);
System.out.println("================================="); //#person.name获取根对象person的name属性, #person代表的person这个对象,如要拿到某个对象要使用#
obj = Ognl.getValue(Ognl.parseExpression("#person.name"), context, context.getRoot());
System.out.println(obj);
System.out.println("================================="); //#dog表示的是context.put("dog", dog)这个对象
obj = Ognl.getValue("#dog.name", context, context.getRoot());
System.out.println(obj);
System.out.println("=================================="); //此时name表示的是person这个根对象的属性,直接写上属性名即可
obj = Ognl.getValue("name", context, context.getRoot());
System.out.println(obj);
} catch (Exception e) {
e.printStackTrace();
}
}

输出结果:

wangwang

================================================

zhagnsan

================================================

wangcai

================================================

zhagnsan

2.2.2 方法调用

@Test
public void test2(){
try{
Person person = new Person();
person.setName("zhagnsan"); OgnlContext context = new OgnlContext();
context.put("person", person); context.setRoot(person); //可以直接调用方法,name是根对象person的属性
Object obj = Ognl.getValue("name.toUpperCase().length()", context, context.getRoot());
System.out.println(obj);
System.out.println("=================================");
} catch (Exception e) {
e.printStackTrace();
}
}

输出结果: 8

2.2.3 调用静态方法

@Test
public void test3(){
OgnlContext context = new OgnlContext();
try {
//调用静态方法的语法: @类的全名@静态方法名
Object obj = Ognl.getValue("@java.lang.Integer@toBinaryString(10)", context, context.getRoot());
System.out.println(obj);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:1010

2.2.4 java.lang.Math的处理

@Test
public void test4(){
OgnlContext context = new OgnlContext();
try {
//java.lang.Math为ognl的内置对象,@@即可表示对java.lang.Math的引用
Object obj = Ognl.parseExpression("@@min(10, 4)");
obj = Ognl.getValue(obj, context, context.getRoot());
System.out.println(obj);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:4

2.2.5 List集合的处理

@Test
public void test5(){
OgnlContext context = new OgnlContext();
try {
Object obj = Ognl.getValue("{'aa', 'bb', 'cc'}", context, ontext.getRoot());
System.out.println(obj instanceof List);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:true

@Test
public void test7(){
OgnlContext context = new OgnlContext();
try {
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("welcome");
context.put("list", list); Object obj = Ognl.getValue("#list[1]", context, context. getRoot());
System.out.println(obj);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:world

2.2.6 Map集合

@Test
public void testMap(){
OgnlContext context = new OgnlContext();
try {
/*
Map<String, String> map = new HashMap<String, String>();
map.put("aa", "abc");
map.put("bb", "zz");
map.put("cc", "gg"); context.put("map", map); Object obj = Ognl.getValue("#map['aa']", context, context.getRoot());
*/
Object obj = Ognl.getValue("#{'aa':'zz', 'bb':'cc', 'dd':'xx'}['aa']", context, context.getRoot());
System.out.println(obj);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:zz

2.2.7 过滤

//过滤,语法格式Collection.{? expr},返回的是一个集合
@Test
public void testFilter(){
OgnlContext context = new OgnlContext();
try {
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("welcome");
list.add("helloworld");
context.put("list", list); /*
Object obj = Ognl.getValue("#list.{? #this.length() gt 5}", context, context.getRoot());
System.out.println(obj);
*/
//Object obj = Ognl.getValue("#list.{? #this.length() gt 5}.size()", context, context.getRoot()); //size是伪属性,isEmpty也是伪属性
Object obj = Ognl.getValue("#list.{? #this.length() gt 5}.size", context, context.getRoot());
System.out.println(obj);
System.out.println("==============================");
/**
* collectoin.{^ expr} 获取到过滤后的集合中的第一个元素
*/
obj = Ognl.getValue("#list.{^ #this.length() > 5}", context, context.getRoot());
System.out.println(obj);
System.out.println("=============================="); /**
* collectoin.{$ expr} 获取到过滤后的集合中的最后一个元素
*/
obj = Ognl.getValue("#list.{$ #this.length() > 5}[0]", context, context.getRoot());
System.out.println(obj);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:

2

==============================

[welcome]

==============================

helloworld

2.2.8 投影

/**
* 投影 collection.{expr}, 返回的依然是集合,并且长度不会变化,仅仅只是属性的个数发生的变化。拿数据库来类比:过滤相当于取行的操作(行数的可能会变化),投影相当于数据库的取列的操作。
*/
@Test
public void testProjectoin(){
OgnlContext context = new OgnlContext();
try {
List<Person> list = new ArrayList<Person>();
Person p1 = new Person();
p1.setName("zhangsan"); Person p2 = new Person();
p2.setName("lisi"); Person p3 = new Person();
p3.setName("wangwu");
list.add(p1);
list.add(p2);
list.add(p3);
context.put("list", list); /*//将List中每个Person的name取出来,放到一个集合中
//Object obj = Ognl.getValue("#list.{name}", context, context.getRoot());
Object obj = Ognl.getValue("#list.{#this.name}", context, context.getRoot()); //与上一行代码实现相同的功能
System.out.println(obj);
*/
//当名字长度大于5,就用helloworld来替换,否则保持不变
//Object obj = Ognl.getValue("#list.{#this.name.length() > 5 ? 'helloworld' : #this.name}", context, context.getRoot());
Object obj = Ognl.getValue("#list.{name.length() > 5 ? 'helloworld' : name}", context, context.getRoot()); //与上一行代码实现相同的功能
System.out.println(obj);
} catch (OgnlException e) {
e.printStackTrace();
}
}

输出结果:

[helloworld, lisi, helloworld]

下一篇:Struts2对Ognl的支持

OGNL语言的更多相关文章

  1. java struts2入门学习--OGNL语言基本用法

    一.知识点学习 1.struts2中包含以下6种对象,requestMap,sessionMap,applicationMap,paramtersMap,attr,valueStack; 1)requ ...

  2. java struts2入门学习--防止表单重复提交.OGNL语言学习

    一.知识点回顾 防止表单重复提交核心思想: 客户端和服务器端和写一个token,比较两个token的值相同,则非重复提交;不同,则是重复提交. 1.getSession三种方式比较: request. ...

  3. java struts2入门学习--OGNL语言常用符号和常用标签学习

    一.OGNL常用符号(接上一篇文章): 1.#号 1)<s:property value="#request.username"/> 作用于struts2的域对象,而不 ...

  4. JavaWeb框架SSH_Struts2_(四)----->表达式语言OGNL

    1. 表达式语言OGNL OGNL简介 OGNL基本语法 常量 操作符 OGNL表达式 OGNL基础 OGNL上下文 OGNL值栈 OGNL的访问 2. 具体内容 2.1 OGNL简介 OGNL(Ob ...

  5. JavaWeb框架_Struts2_(四)----->表达式语言OGNL

      2. 表达式语言OGNL 2.1 OGNL简介 OGNL(Object-Graph Navigation Language)对象图导航语言的缩写,OGNL是一种表达式语言(Expression L ...

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

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

  7. el 表达式 和 ognl表达式

    el (expression language) el 基础操作符 el 能够隐含对象(就是可以直接访问的) el 的两种使用方式,第二种好像在jsp中没有什么用,主要用于jsf el能够访问的对象( ...

  8. Struts2对Ognl的支持

                                                      Struts2对Ognl的支持 一. 写作背景 由于工作性质的变化,最近一直在研究struts2,从 ...

  9. Struts2(3) —— 数据处理

    Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:ValueStack一种数据结构,操作数据的方式为 ...

随机推荐

  1. shell脚本参数

    举例说:脚本名称叫test.sh 入参三个: 1 2 3运行test.sh 1 2 3后$*为"1 2 3"(一起被引号包住)$@为"1" "2&qu ...

  2. user-select : 保护版权内容的简单方案

    有的适合我们需要保护我们页面的内容,为了版权或者安全等原因,这个适合我们可以使用 user-select 这个CSS属性,简单易用. 嗯,这个属性不麻烦,而且也不是 CSS 3 / CSS 4 的新属 ...

  3. 无任何网络提供程序接受指定的网络路径(系统服务里没有workstation服务)

    今天同事访问公司服务器时,提示“无任何网络提供程序接受指定的网络路径”,网络ping正常,把防火墙关掉,再次尝试问题如故. 于是上网搜索: 1.服务停止:一般有workstation,server,c ...

  4. iOS开发拓展篇—CoreLocation定位服务

    iOS开发拓展篇—CoreLocation定位服务 一.简单说明 1.CLLocationManager CLLocationManager的常用操作和属性 开始用户定位- (void)startUp ...

  5. iOS开发网络篇—使用ASI框架进行文件下载

    iOS开发网络篇—使用ASI框架进行文件下载 说明:本文介绍iOS网络编程中经常用到的框架ASI,如何使用该框架进行文件的下载. 一.简单介绍 代码示例: #import "YYViewCo ...

  6. hadoop运行原理之Job运行(三) TaskTracker的启动及初始化

    与JobTracker一样,TaskTracker也有main()方法,然后以线程的方式启动(继承了Runnable接口).main()方法中主要包含两步:一是创建一个TaskTracker对象:二是 ...

  7. 搭建Android工程的步骤及其第一个安卓程序

    1.安卓系统架构 1>底层是Linux系统 2>函数库层 由C或C++写的 3>Application frameWork应用的框架层 4>顶层是应用层 2.JVM与DVM介绍 ...

  8. js事件捕获,事件冒泡,事件委托以及DOM事件流

    一:DOM事件流: 事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段: ①事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body ...

  9. JDBCl链接中Statement

    作用:创建的Statement对象执行SQL语句 (1)对象有Connection对象调用createStatement()方法创建 (2)有Statement对象调用executeUpdate()方 ...

  10. 团队开发——冲刺1.c

    冲刺阶段一(第三天) 1.昨天做了什么? 在C#的Windows窗体应用程序中,设计简单的游戏界面. 2.今天准备做什么? 首先把昨天遇到的问题解决了,虽然没有找到原因,但是只要每一步修改后就立即运行 ...