来源:http://www.24xuexi.com/w/2011-04-26/88911.html

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)" />

JSP视图

showognl.jsp是使用了OGNL表达式的JSP视图,视图用来显示Action中处理的各种信息,读者可以看到,使用OGNL表达式,代码更加简洁和直观,如代码8.5所示。

代码8.5 使用OGNL表达式的JSP视图

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>

<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Struts2 OGNL 演示</title>

</head>

<body>

<h3>访问OGNL上下文和Action上下文</h3>

<!-使用OGNL访问属性值-->

<p>parameters: <s:property value="#parameters.msg" /></p>

<p>request.msg: <s:property value="#request.msg" /></p>

<p>session.msg: <s:property value="#session.msg" /></p>

<p>application.msg: <s:property value="#application.msg" /></p>

<p>attr.msg: <s:property value="#attr.msg" /></p>

<hr />

<h3>用于过滤和投影(projecting)集合</h3>

<p>年龄大于20</p>

<ul>

<!-判断年龄-->

<s:iterator value="persons.{?#this.age>20}">

<li><s:property value="name" /> - 年龄:<s:property value="age" /></li>

</s:iterator>

</ul>

<p>姓名为pla1的年龄: <s:property value="persons. {?#this.name=='pla1'} .{age}[0]"/></p>

<hr />

<h3>构造Map</h3>

<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />

<p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>

</body>

</html>

OGNL中的#、%和$符号

#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分。在这里笔者简单介绍它们的相应用途。

1.#符号

#符号的用途一般有三种。

― 访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute("msg")。

― 用于过滤和投影(projecting)集合,如示例中的persons.{?#this.age>20}。

― 用来构造Map,例如示例中的#{'foo1':'bar1','foo2':'bar2'}。

2.%符号

%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。如下面的代码所示:

<h3>构造Map</h3>

<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />

<p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>

<p>不使用%:<s:url value="#foobar['foo1']" /></p>

<p>使用%:<s:url value="%{#foobar['foo1']}" /></p>

运行界面如图8.4所示。

3.$符号

$符号主要有两个方面的用途。

― 在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

― 在Struts 2框架的配置文件中引用OGNL表达式,例如下面的代码片断所示:

<validators>

<field name="intb">

<field-validator type="int">

<param name="min">10</param>

<param name="max">100</param>

<message>BAction-test校验:数字必须为${min}为${max}之间!</message>

</field-validator>

</field>

</validators>

Struts 2的OGNL表达式相关推荐

  1. Struts标签和OGNL表达式

    Struts标签和OGNL表达式 1.OGNL通过索引访问ValueStack中的对象. [0].name [1].name 上面使用的索引的方式并不是直接取得指定元素,而是从指定索引开始向下搜索. ...

  2. Struts(十):OGNL表达式(一)

    Struts2 用s:porperty标签和OGNL表达式来读取值栈中的属性值: I.值栈中的属性值: 1.对象栈:读取对象栈中的某一个对象的属性值: 2.Map栈 :request,session, ...

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

    来自:http://blog.csdn.net/love_you_99/article/details/8184797 一 介绍 1.Struts2的作用 Struts2标签库提供了主题.模板支持,极 ...

  4. Struts(十一):OGNL表达式(二)

    Map栈 :request,session,application的一个属性值或一个请求参数的值. 若想访问ContextMap里的某个对象的属性,可以使用以下几种之一: #object.proper ...

  5. struts OGNL表达式

    OGNLContext对象有两部分构成 一部分是ROOT:可以放置任何对象作为ROOT 另外一部分Context:必须是Map形式(键值对) OGNL表达式操作 package cn.future.a ...

  6. 关于OGNL表达式中的%,$,#

    OGNL表达式非常强大-其中#.%.$这三个符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,要认真区分.   1.#符号的用途一般有三种. 1)访问非根对象属性,例如示例 ...

  7. 深入理解Struts2中的OGNL表达式

    Struts 2中的表达式语言 Struts 2支持以下几种表达式语言: OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言: JST ...

  8. Struts2漏洞分析之Ognl表达式特性引发的新思路

    摘要 在Ognl表达式中,会将被括号"()"包含的变量内容当做Ognl表达式执行.Ognl表达式的这一特性,引发出一种新的攻击思路.通过将恶意代码存储到变量中,然后在调用Ognl表 ...

  9. struts2教程(9)--OGNL表达式使用

    OGNL表示式使用和值栈 一.介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的 ...

最新文章

  1. mysql在linux下的安装
  2. GDAL Data Model(转)
  3. .Net 中HashTable,HashMap 和 Dictionarykey,value 和ListT和DataTable的比较
  4. html 入门例子(二) 折行
  5. VC控件自绘制三步曲
  6. php中的session机制
  7. index 生成创建index的脚本
  8. Java笔记-JdbcTemplate批量执行insert及update
  9. gradle拷贝静态资源文件_Gradle复制文件/目录方法
  10. Bailian2870 求矩阵的加法【矩阵】
  11. String的indexOf()用于获取字符串中某个子字符串的位置
  12. 四、登录注册页功能实现《iVX低代码/无代码个人博客制作》
  13. 源码解析zxing条码边距及总宽度计算规则,附java使用zxing生成条形码,并去除条码两边空白
  14. UDF函数:对字符串实现sha256加密,返回64位十六进制字符串
  15. element-ui图标不显示问题(已解决)
  16. 榆熙电商:拼多多怎样判断商品是否被降权?原因有哪些?
  17. 记忆化搜索 (蒟蒻练习生)
  18. 证券行业基础知识(二)
  19. python获取网卡的ip子网掩码和网关
  20. 入门级||如何通过录屏软件提高学习效率

热门文章

  1. C#跨线程操作控件的线程安全方法
  2. oracle数据库多表联查并排序,oracle数据库之多表联接查询(一)
  3. led透明屏生产厂家_如何实现LED双面透明显示屏,双面LED透明屏
  4. Android开发之可以在任意页面开启主线程和使用线程池开启子线程的工具类
  5. 使用git命令提交代码到Github远程仓库的方法
  6. android 多个handler,Android中的Handler与多线程应用实例
  7. java线程不执行_java线程池,阿里为什么不允许使用Executors?
  8. 关于 VC 执行顺序
  9. UIApplication详解
  10. 最长对称字符串php_有哪些像TENET一样中心对称的英语单词(误)