首先了解下OGNL的概念

OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。

此外,还得先需弄懂OGNL的一些知识:

1.OGNL表达式的计算是围绕OGNL上下文进行的。
OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。
上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:propertyvalue="xxx"/>。
3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。
4.值栈(ValueStack) :
可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。
Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
 
5.调用ActionContext的put(key,value)放入的数据,需要使用#访问。

OGNL中重要的3个符号:#、%、$:

#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,需要时间的积累才渐渐弄清楚……
1.#符号

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

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

—    用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。

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

2.%符号

%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值,这个类似js中的eval,很暴力。

3.$符号

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

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

======================================================Strust2 中 OGNL堆栈的原理和实现=============================================================

访问属性

名字属性获取 :<s:property value="user.username"/><br>

地址属性获取 :<s:property value="user.address.addr"/><br>

访问方法

调用值栈中对象的普通方法: <s:property value="user.get()"/><br>

访问静态属性和方法

调用 Action 中的静态方法: <s:property value="@struts.action.LoginAction@get()"/>

调用 JDK 中的类的静态方法: <s:property value="@java.lang.Math@floor(44.56)"/><br>

调用 JDK 中的类的静态方法 ( 同上 ) : <s:property value="@@floor(44.56)"/><br>

调用 JDK 中的类的静态方法: <s:property value="@java.util.Calendar@getInstance()"/><br>

调用普通类中的静态属性: <s:property value="@struts.vo.Address@TIPS"/><br>

访问构造方法

调用普通类的构造方法 :<s:property value="new struts.vo.Student(' 王老吉 ' , ' 爱国饮料 ' , 3 , 99).username"/>

1.5. 访问数组

获取 List:<s:property value="testList"/><br>

获取 List 中的某一个元素 ( 可以使用类似于数组中的下标获取 List 中的内容 ):

<s:property value="testList[0]"/><br>

获取 Set:<s:property value="testSet"/><br>

获取 Set 中的某一个元素 (Set 由于没有顺序,所以不能使用下标获取数据 ):

<s:property value="testSet[0]"/><br> ×

获取 Map:<s:property value="testMap"/><br>

获取 Map 中所有的键 :<s:property value="testMap.keys"/><br>

获取 Map 中所有的值 :<s:property value="testMap.values"/><br>

获取 Map 中的某一个元素 ( 可以使用类似于数组中的下标获取 List 中的内容 ):

<s:property value="testMap['m1']"/><br>

获取 List 的大小 :<s:property value="testSet.size"/><br>

访问集合 – 投影、选择 (? ^ $)

利用选择获取 List 中成绩及格的对象 :<s:property value="stus.{?#this.grade>=60}"/><br>

利用选择获取 List 中成绩及格的对象的 username:

<s:property value="stus.{?#this.grade>=60}.{username}"/><br>

利用选择获取 List 中成绩及格的第一个对象的 username:

<s:property value="stus.{?#this.grade>=60}.{username}[0]"/><br>

利用选择获取 List 中成绩及格的第一个对象的 username:

<s:property value="stus.{^#this.grade>=60}.{username}"/><br>

利用选择获取 List 中成绩及格的最后一个对象的 username:

<s:property value="stus.{$#this.grade>=60}.{username}"/><br>

利用选择获取 List 中成绩及格的第一个对象然后求大小 :

<s:property value="stus.{^#this.grade>=600}.{username}.size"/><br>

集合的伪属性

OGNL 能够引用集合的一些特殊的属性 , 这些属性并不是 JavaBeans 模式 , 例如 size(),length() 等等 . 当表达式引用这些属性时 ,OGNL 会调用相应的方法 , 这就是伪属性 .

集合

伪属性

Collection(inherited by Map, List & Set)

size ,isEmpty

List

iterator

Map

keys , values

Set

iterator

Iterator

next , hasNext

Enumeration

next , hasNext , nextElement , hasMoreElements

Lambda   :[…]

格式: :[…]

使用 Lambda 表达式计算阶乘 :

<s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br>

OGNL 中 # 的使用

# 可以取出堆栈上下文中的存放的对象 .

名称

作用

例子

parameters

包含当前 HTTP 请求参数的 Map

#parameters.id[0] 作用相当于

request.getParameter("id")

request

包含当前 HttpServletRequest 的属性( attribute) 的 Map

#request.userName 相当于

request.getAttribute("userName")

session

包含当前 HttpSession 的属性( attribute)的 Map

#session.userName 相当于

session.getAttribute("userName")

application

包含当前应用的 ServletContext 的属性(attribute )的 Map

#application.userName 相当于

application.getAttribute("userName")

attr

用于按 request > session > application 顺序访问其属性( attribute )

获取 Paraments 对象的属性: <s:property value="#parameters.username"/>

OGNL 中 % 的使用

用 %{} 可以取出存在值堆栈中的 Action 对象 , 直接调用它的方法 .

例如你的 Action 如果继承了 ActionSupport . 那么在页面标签中,用 %{getText('key')} 的方式可以拿出国际化信息 .

OGNL 中 $ 的使用

“ $ ”有两个主要的用途

l          用于在国际化资源文件中,引用 OGNL 表达式

l          在 Struts 2 配置文件中,引用 OGNL 表达式

值栈

ValueStack 对象。这个对象贯穿整个 Action 的生命周期(每个 Action 类的对象实例会拥有一个 ValueStack 对象)。当 Struts 2 接收到一个 .action 的请求后,会先建立 Action 类的对象实例,但并不会调用Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点( ValueStack 对象相当于一个栈)。

在 Action 中获得 ValueStack 对象: ActionContext.getContext().getValueStack()

l          Top 语法

使用 Top 获取值栈中的第二个对象 :<s:property value="[1].top. 对象 "/>

l          N 语法

使用 N 获取值栈中的第二个对象 :<s:property value="[1]. 对象 "/>

l          @ 语法

调用 action 中的静态方法: <s:property value="@vs1@ 静态方法 "/> vs :值栈 1 :表示第一个。

 

Strust OGNL详解的更多相关文章

  1. OGNL详解

    A.什么是OGNL? 全称叫ObjectGraphic Navigation Language(对象图导航语言),它是struts2框架里面的第三方语言(即可以再别的地方用,struts2只是拿过来了 ...

  2. struts2中的OGNL详解

    先了解一下OGNL的概念 OGNL的全名称Object Graph Navigation Language.全称为对象图导航语言,是一种表达式语言.使用这种表达式语言,你可以通过某种表达式语法,存取J ...

  3. Struts2_ValueStack,OGNL详解(转)

    原文地址:http://blog.csdn.net/wyply115/article/details/8257140 一.OGNL表达式 1.ognl是struts2中使用的一种表达式语言,可用于js ...

  4. Struts2_ValueStack,OGNL详解

    一.ValueStack    1.ValueStack是一个接口,在struts2中使用OGNL(Object-Graph Navigation Language)表达式实际上是使用实现了Value ...

  5. java框架篇---struts之OGNL详解

    OGNL(Object Graph Navigation Language),是一种表达式语言.使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性.调用Java对象树的方法. ...

  6. Struts2中的OGNL详解 《转》

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

  7. struts OGNL详解

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

  8. struts2中的ognl详解,摘抄

    http://blog.csdn.net/tjcyjd/article/details/6850203     很全很细致,自己再分析原理进阶

  9. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...

随机推荐

  1. 计算机程序的思维逻辑 (29) - 剖析String

    上节介绍了单个字符的封装类Character,本节介绍字符串类.字符串操作大概是计算机程序中最常见的操作了,Java中表示字符串的类是String,本节就来详细介绍String. 字符串的基本使用是比 ...

  2. 增强学习(二)----- 马尔可夫决策过程MDP

    1. 马尔可夫模型的几类子模型 大家应该还记得马尔科夫链(Markov Chain),了解机器学习的也都知道隐马尔可夫模型(Hidden Markov Model,HMM).它们具有的一个共同性质就是 ...

  3. 【分布式】Zookeeper系统模型

    一.前言 前面已经讲解了Zookeeper的一些应用场景,但是并没有深入到Zookeeper内部进行分析,本篇将讲解其系统模型. 二.系统模型 2.1 数据模型 Zookeeper的数据节点称为ZNo ...

  4. 妥协与取舍,解构C#中的小数运算

    题外话 正文开始之前,我首先要感谢博客园提供的这个优秀的平台.通过在这个优秀的平台上和很多志同道合的朋友交流,互相帮助,我也很荣幸的获得了15年的微软MVP的奖项.也使我更加坚信了代码改变世界.感激! ...

  5. PHP实现删除数组中的特定元素

    方法1: <?php $arr1 = array(1,3, 5,7,8); $key = array_search(3, $arr1); if ($key !== false) array_sp ...

  6. 【十大经典数据挖掘算法】SVM

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART SVM(Support Vector ...

  7. JSTL标签 参考手册

    前言 ========================================================================= JSTL标签库,是日常开发经常使用的,也是众多 ...

  8. Kafka 如何读取offset topic内容 (__consumer_offsets)

    众所周知,由于Zookeeper并不适合大批量的频繁写入操作,新版Kafka已推荐将consumer的位移信息保存在Kafka内部的topic中,即__consumer_offsets topic,并 ...

  9. 使用Expression实现数据的任意字段过滤(2)

    上一篇<使用Expression实现数据的任意字段过滤(1)>, 我们实现了通过CriteriaCollectionHandler对象来处理集合数据过滤.通过适当的扩展, 应该可以满足一般 ...

  10. JDBC 详解(转载)

    原文链接:http://blog.csdn.net/cai_xingyun/article/details/41482835 什么是JDBC? Java语言访问数据库的一种规范,是一套API JDBC ...