`
sunnyday55555
  • 浏览: 62847 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

OGNL基础知识

阅读更多
OGNL 是Object Graphic Navigation Language(对象图导航语言)的缩写,OGNL是一个开源项目,读者可以访问其官方站点www.ognl.org以获得源代码和相关资料。OGNL 是一种功能强大的EL(Expression Language,表达式语言),可以通过简单的表达式来访问Java对象中的属性。

OGNL先在WebWork项目中得到应用,也是Struts 2框架视图默认的表达式语言,可以说,OGNL表达式是Struts 2框架的特点之一。

8.1 OGNL基础知识

8.1.1 OGNL的优势

同以往的技术相比,OGNL有哪些优势呢?总结起来有如下几个方面。

—    OGNL是将视图元素(例如textfield、combobox等)同模型对象绑定在一起的一种语言。使用OGNL的类型转换功能,会使类型转换变得更加简单(例如将一个字符串类型转换为一个整数类型)。

—    表格元素同Swing TableModel对应的一种数据源语言。

—    可以将Web页面元素同后台服务器业务对象对应起来。

—    比JSTL(JSP标准标签库)表达更加丰富。

8.1.2 OGNL语法

基本的OGNL语法是十分简单的,当然OGNL支持丰富的表达式,一般情况下,不用担心OGNL的复杂性。例如有一个man对象,该对象有一个name属性,那么使用OGNL来获得该name属性可以使用如下表达式:

man.name

OGNL表达式的基础单元称为导航链,简称为链。一个最简单的链由如下部分组成。

—    属性名称:如上述示例中的name。

—    方法调用:hashCode()返回当前对象的hash code。

—    数组元素:listeners[0]返回当前对象的监听器列表中的第一个元素。

★ 说明 ★

OGNL表达式基于OGNL上下文中的当前对象,一个“链”将使用上一个“链”的处理结果,开发者可以任意扩展该链的长度,OGNL没有限制。

(1.2.3.4.5 是先执行1.2然后执行(1.2).3 然后执行 ((1.2).3).4 这样的)

例如,一个OGNL表达式如下:

name.toCharArray()[0].numericValue.toString()

该表达式将按照如下步骤求值。

(1)获得OGNL Context中初始对象或者是根对象(root对象)的name对象。

(2)调用toCharArray()方法,返回一个String类型对象。

(3)获得该String对象的第一个字符。

(4)获得该字符的numericValue属性(该字符为一个Character对象,该对象有一个getNumericValue()方法,该方法返回一个Integer类型值)。

(5)将获得的Integer对象转换为一个String类型值(使用toString()方法)。
8.1.3 一个使用OGNL的示例

下面笔者以一个简单的示例来帮助读者理解OGNL表达式。使用OGNL表达式,需要在www.ognl.org网站下载一个ognl.jar插件包,将该文件复制到classpath路径下即可。建立一个复合类型,如代码8.1所示。

代码8.1 定义复合类型

package ch8;

import java.util.Date;

//团队类

public class Team {

    // 团队名称

    private String teamname;

    // 定义团队人员属性

    private Person person;

    // 团队人数

    private int personnum;

    //属性的getter和setter方法

    public String getTeamname() {

        return teamname;

    }

    public void setTeamname(String teamname) {

        this.teamname = teamname;

    }

    public Person getPerson() {

        return person;

    }

    public void setPerson(Person person) {

        this.person = person;

    }

    public int getPersonnum() {

        return personnum;

    }

    public void setPersonnum(int personnum) {

        this.personnum = personnum;

    }

}

// 定义人员类

class Person {

    // 姓名

    private String name;

    // 年龄

    private int age;

    // 人员出生日期

    private Date birthday;

    //属性的getter和setter方法

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public Date getBirthday() {

        return birthday;

    }

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

}

代码8.1所示内容定义了两个复合类型:团队(team)和人员(person)类型。使用OGNL表达式示例,如代码8.2所示。

代码8.2 使用OGNL表达式示例

package ch8;

import java.util.HashMap;

import java.util.Map;

import ognl.Ognl;

import ognl.OgnlException;

public class TestOGNL {

        public static void main(String[] args) {

        //定义一个Map对象

        Map m = new HashMap();

        //定义一个Team对象

        Team team1 = new Team();

        team1.setTeamname("团队1");

        //定义一个Person对象

        Person person1 = new Person();

        person1.setName("pla1");

        //添加team元素

        team1.setPerson(person1);

        //定义一个Team对象

        Team team2 = new Team();

        team2.setTeamname("团队2");

        //定义一个Person对象

        Person person2 = new Person();

        person2.setName("pla2");

        //添加team元素

        team2.setPerson(person2);

      

        //添加Map元素

        m.put("team1", team1);

        m.put("team2", team2);

        try {

            System.out.println(Ognl.getValue("team1.teamname", m));

            System.out.println(Ognl.getValue("team2.person.name", m));

            System.out.println(Ognl.getValue("teamname", team2));

            System.out.println(Ognl.getValue("person.name", team2));

        } catch (OgnlException e) {

        }

    }

}

代码8.2所示内容定义了一个Map类型的嵌套属性,如图8.1所示。

图8.1 嵌套属性示意图

运行该示例,控制器显示如下信息:

团队1

pla2

团队2

pla2

★ 说明 ★

OGNL可以使用非常简单的表达式来访问多层嵌套属性,为开发者提供了一个有力的工具。
8.2 Struts 2的OGNL

OGNL是Struts 2框架的默认表达式语言,增强了Struts 2的数据访问能力,同时简化了代码。
8.2.1 Struts 2的OGNL表达式

标准的OGNL会设定一个根对象(root对象)。假设使用标准OGNL表达式来求值(不使用Struts 2的OGNL表达式),如果OGNL上下文(OgnlContext Map类型)有两个对象:foo对象,在OgnlContext中名称为foo;bar对象,在OgnlContext中名称为bar。同时foo对象被设置为根对象(root)。则利用下面的OGNL表达式求值:

// 返回foo.getBlah()

#foo.blah

//返回bar.getBlah()

#bar.blah

//返回foo.getBlah() ,因为foo为根对象

blah

★ 说明 ★

使用OGNL是非常简单的,如果要访问的对象不是根对象,如示例中的bar对象,则需要使用命名空间,用“#”来标识,如“#bar”;如果访问一个根对象,则不用指定命名空间,可以直接访问根对象的属性。

在Struts 2框架中,值栈(Value Stack)就是OGNL的根对象,假设值栈中存在两个对对象实例:Man和Animal,这两个对象实例都有一个name属性,Animal有一个 species属性,Man有一个salary属性,假设Animal在值栈的顶部,Man在Animal后面,下面的代码片断会帮助读者更好地理解 OGNL表达式:

// 调用animal.getSpecies()

species

// 调用man.getSalary()

salary

// 调用animal.getName(),因为Animal位于值栈的顶部

name

最后一行示例代码,返回的是animal.getName()返回值,即返回了Animal的name属性,因为Animal是值栈的顶部元素,OGNL将从顶部元素搜索,所以会返回Animal的name属性值。如果要获得Man的name值,则需要如下代码:

man.name

Struts 2允许在值栈中使用索引,示例代码如下所示:

[0].name   // 调用animal.getName()

[1].name   // 调用man.getName()

★ 说明注意 ★

使用索引,并不是直接获得指定的元素,而是从指定的索引位置搜索。

Struts 2中的OGNL Context是ActionContext,如图8.2所示。

图8.2 Struts 2的OGNL Context结构示意图

★ 说明 ★

图8.2只是说明Struts 2的OGNL Context结构,实际上Context还包含其他对象。

由于值栈是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,则可以直接通过下面的代码访问值栈中的属性:

//获得值栈中的foo属性

${foo}

如果访问其他Context中的对象,由于不是根对象,在访问时,需要加#前缀。

—    application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用Servlet的getAttribute("username")。

—    session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。

—    request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.get力Attribute ("userName")。

—    parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。

—    attr对象:用于按page-request-session-application顺序访问其属性。
8.2.2 OGNL的集合操作

如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。

可以使用如下代码直接生成一个List对象:

{e1,e2,e3…}

该OGNL表达式中,直接生成了一个List对象,该List对象中包含3个元素:e1、e2和e3。如果需要更多的元素,可以按照这样的格式定义多个元素,多个元素之间使用逗号隔开。

如下代码可以直接生成一个Map对象:

#{key1:value1,key2:value2,…}

Map类型的集合对象,使用key-value格式定义,每个key-value元素使用冒号标识,多个元素之间使用逗号隔开。

对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如代码8.3所示。

代码8.3 使用OGNL集合操作符

<s:if test="'foo' in {'foo','bar'}">

   muhahaha

</s:if>

<s:else>

   boo

</s:else>

<s:if test="'foo' not in {'foo','bar'}">

   muhahaha

</s:if>

<s:else>

   boo

</s:else>

除了in和not in之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。

—    ?:获得所有符合逻辑的元素。

—    ^:获得符合逻辑的第一个元素。

—    $:获得符合逻辑的最后一个元素。

例如代码:

person.relatives.{? #this.gender == 'male'}

该代码可以获得person的所有性别为male的relatievs集合。
8.2.3 Lambda表达式

OGNL支持基本的Lambda表达式语法,通过Lambda表达式语法,可以在OGNL中使用一些简单的函数。例如:

Fibonacci:

if n==0 return 0;

elseif n==1 return 1;

else return fib(n-2)+fib(n-1);

fib(0) = 0

fib(1) = 1

fib(11) = 89

开发者可以使用Lambda表达式语法:

<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
分享到:
评论

相关推荐

    ognl.rar_OGNL API_og_ognl

    **OGNL基础知识** 1. **OGNL简介**:OGNL提供了一种简洁的方式来表示复杂的对象图导航路径。它支持方法调用、索引访问、属性访问,甚至可以进行算术运算和逻辑判断。OGNL表达式可以嵌套,使得它非常灵活且强大。 2...

    struts2中的ongl表达式相关简介

    #### OGNL基础知识 OGNL的主要作用是将视图元素与模型对象绑定在一起。它支持类型转换,使得开发者能够轻松地将一种数据类型转换为另一种类型,例如将字符串转换为整数。此外,OGNL还可以作为一种数据源语言,用于...

    OGNL语言中文资料

    一、OGNL的基础知识 1. **对象导航**:OGNL的名称来源于其核心功能——对象图导航。它可以轻松地遍历对象的属性,甚至通过链式调用来访问嵌套的对象属性,如`person.address.city`,这在处理复杂的对象结构时非常...

    OGNL表达式的使用及文档

    一、OGNL的基础知识 1. **表达式语法**:OGNL表达式通常由对象名、点号和属性名组成,例如`user.name`,表示获取`user`对象的`name`属性。也可以通过索引访问集合元素,如`list[0]`。 2. **上下文(Context)**:在...

    OGNL和XWORK源代码

    下面将详细阐述OGNL和XWork的相关知识点。 **OGNL:** OGNL是一种强大的表达式语言,它被广泛用于Struts2框架中的数据绑定和表达式评估。以下是一些关于OGNL的关键点: 1. **表达式语法**:OGNL表达式可以访问对象...

    ognl-2.6.11.jar源码

    - **ASTNode**: 表示抽象语法树的节点,是OGNL表达式的结构基础。 - **Evaluator**: 根据AST执行表达式,获取或设置对象的值。 - **Context**: 实现了值映射,管理表达式执行时的环境。 - **TypeConverter**: 负责...

    ognl 源码zip

    10. **应用实践**:结合实际项目,尝试使用OGNL解决数据绑定、动态计算等问题,进一步巩固理论知识。 通过对OGNL源码的学习,你可以更深入地理解Java中的反射、动态代理等技术,并能够更好地利用OGNL解决实际问题,...

    struts2详细讲解,JQuery,类型转换和OGNL

    首先,让我们来看看Struts2的基础知识。Struts2是基于Apache的开源项目,它是对早期Struts框架的升级,引入了拦截器模式,提供了更灵活的控制流程。在Struts2中,Action类是处理用户请求的核心,每个Action对应一个...

    Struts2 使用OGNL表达式

    以下是一些关于Struts2中OGNL表达式的关键知识点: 1. **基础语法**:OGNL表达式的格式通常为`object.property`或`object[index]`,用于访问对象的属性或数组/集合的元素。例如,`user.name`将获取名为`user`的对象...

    ognl源代码(可以省去不少麻烦)

    2. **表达式解析**:OGNL源代码中的解析器将字符串表达式转化为抽象语法树(AST),这是执行表达式的基础。解析过程涉及到词法分析和语法分析两个阶段。 3. **对象绑定**:OGNL允许在一个上下文中绑定多个对象,...

    ognl.rar_OGNL API_struts2 ognl api_struts2帮助文档

    通过学习这些知识点,开发者能够更高效地使用OGNL进行数据绑定和表达式处理,从而提升Struts2应用的开发效率和质量。在实际项目中,理解并熟练运用OGNL API不仅可以帮助开发者更好地控制应用程序的数据流,还可以为...

    struts2 OGNL表达式

    1. **OGNL基础语法**:包括变量引用、属性访问、集合操作、方法调用等。 2. **Struts2动作和结果**:如何在配置文件中使用OGNL定义Action和结果。 3. **JSP标签库**:Struts2提供的JSP标签库,如`s:property`、`s:...

    ognl guide

    下面将详细介绍OGNL的基础知识、语法以及表达式用法。 ### OGNL概述 OGNL提供了一种简洁的方式来访问和操作Java对象的属性,甚至可以跨越对象关系图。它支持动态计算和方法调用,允许在运行时创建复杂的表达式。这...

    ognl-2.6.7-doc

    2. **语法基础**:讲解OGNL的表达式语法,包括访问对象属性、调用方法、数组和集合操作、条件语句、循环语句等。 3. **OGNL在Struts2和Spring中的应用**:如果OGNL主要用于这两个框架,文档可能会深入讨论如何在...

    经典的ognl详细教程

    OGNL,全称Object-Graph Navigation Language,是一种强大的表达式语言,专为存取对象的属性、...无论是在Web应用开发、Spring框架或其他使用OGNL的项目中,掌握这些基础知识都将极大地提高你的开发效率和代码质量。

    struts2基础知识

    本篇文章将深入探讨Struts2的基础知识,包括其核心概念、工作原理、主要特性以及如何创建一个简单的Struts2应用。 首先,我们来理解一下Struts2的核心概念。Struts2框架整合了Struts1和WebWork的优势,提供了一个...

    STRUTS2+ognl

    本文将详细介绍Struts2、Webwork以及Ognl的相关知识点,并提供入门指导。 **Struts2框架** Struts2是在原有的Struts1基础上发展起来的,它整合了Webwork框架的优势,提供了更灵活的控制流和更强大的拦截器机制。...

    OGNL中文参考手册.pdf

    ### OGNL中文参考手册知识点概述 ...以上内容总结了OGNL中文参考手册的关键知识点,包括OGNL的定义、应用场景、历史发展、语法基础以及表达式的具体细节。希望这些信息能帮助您更好地理解和使用OGNL语言。

    struts2 ognl

    本示例将深入探讨OGNL的基础知识及其在Struts2中的应用。 OGNL是一个强大的表达式语言,它的主要功能包括: 1. **数据访问**:OGNL允许开发者通过简单的表达式访问对象图中的任何属性。例如,`user.name`可以用来...

Global site tag (gtag.js) - Google Analytics