OGNL语言

                                                         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("@[email protected](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]

时间: 2024-08-16 02:43:15

OGNL语言的相关文章

如何自学Struts2之Struts2值栈和OGNL语言[视频]

如何自学Struts2之Struts2值栈和OGNL语言[视频] 之前写了一篇"打算做一个视频教程探讨如何自学计算机相关的技术",优酷上传不了,只好传到百度云上: http://pan.baidu.com/s/1kTDsa95

JavaWeb框架_Struts2_(四)-----&gt;表达式语言OGNL

1. 表达式语言OGNL OGNL简介 OGNL基本语法 常量 操作符 OGNL表达式 OGNL基础 OGNL上下文 OGNL值栈 OGNL的访问 2. 具体内容 2.1 OGNL简介 OGNL(Object-Graph Navigation Language)对象图导航语言的缩写,OGNL是一种表达式语言(Expression Language, EL).可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能. OGNL是一种对java对象的getter和sett

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

struts2标签库主要使用的是OGNL语言,类似于El表达式,但是强大得多,它是一种操作对象属性的表达式语言,OGNL有自己的优点: 能够访问对象的方法,如list.size(); 能够访问静态属性和静态方法,只需要在类名前,方法前加上@,如@[email protected]; 支持赋值操作.如赋值#value=5; 能够访问OGNL上下文和ActionContext; 能操作集合类对象. 使用OGNL: public class Test { public static void main

Struts2对Ognl的支持

                                                  Struts2对Ognl的支持 一. 写作背景 由于工作性质的变化,最近一直在研究struts2,从源码到各个技术点的分析,突然之间发现以前对struts2的ognl这一块的知识覆盖的还不是很全面.再加上笔者身处在深圳这个城市,这些天来一直高温不断,人显得特别的烦躁不安,唯有技术(当然个人爱好还是很广泛的,例如溜冰.篮球.气枪打气球等)能让笔者从燥热中平静下来,故花上几个小时整理了这篇博客,若有失

Thymeleaf3.0简介

thymeleaf的初次使用(带参请求以及调用带参js方法) 之前对于前端框架接触较少,第一次接触thymeleaf,虽说看起来并不复杂但我还是花费了好一会儿才弄懂. 话不多少下面就简单说一下我在项目中的应用. 首先是java代码 controller层 将需要在前端展示的信息放入model中: @RequestMapping("getAll") public String getAll(Model model){ List<ScheduleJob> list = sche

Spring Web MVC框架(十二) 使用Thymeleaf

Thymeleaf简介 前面的例子我们使用的视图技术主要是JSP.JSP的优点是它是Java EE容器的一部分,几乎所有Java EE服务器都支持JSP.缺点就是它在视图表现方面的功能很少,假如我们想迭代一个数组之类的,只能使用<% %>来包括Java语句进行.虽然有标准标签库(JSTL)的补足,但是使用仍然不太方便.另外JSP只能在Java EE容器中使用,如果我们希望渲染电子邮件之类的,JSP就无能为力了. Java生态圈广泛,自然有很多视图框架,除了JSP之外,还有Freemarker.

java项目中可能会使用到的jar包解释

一.Struts2 用的版本是struts2.3.1.1 一个简单的Struts项目所需的jar包有如下8个 1. struts2-core-2.3.1.1.jar: Struts2的核心类库. 2. xwork-core-2.3.1.1.jar: XWork核心类,XWork是一个标准的command模式实现,并且完全从web层剥离出来.WebWork被构建在Xwork上,而Struts2由Struts1和WebWork两个经典的MVC框架发展而来. 3. ognl-3.0.3.jar: 支持

Ibatis动态拼装sql,常用标签总结及举栗子。

今天得到项目经理一项任务,就是拼装sql,第一次见到,不是太懂,赶紧回来睡一觉再说,由于这次的项目orm使用的是ibatis框架,所以需要使用动态拼装sql,或者是ognl语言,这门语言不是专属于ibatis的,而是一门独立的语言,就像EL表达式一样. 首先(摘抄一段,私密马赛,其实可以手写的)使用动态查询时ibatis的一个强大的功能,又是你已经改变WHERE子句条件的基础上你的参数对象的状态,在这种情况下的ibatis提供了一组可以映射语句中标签,这种标签的使用提高了SQL语句的重用性和灵活

Struts2框架学习(三) 数据处理

Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:ValueStack一种数据结构,操作数据的方式为:先进后出 OGNL : Object-GraphNavigation Language(对象图形导航语言)将多个对象的关系使用一种树形的结构展现出来,更像一个图形,那么如果需要对树形结构的节点数据进行操作,那么可以使用 对象.属性 的方式进行操作,OGNL技