先从一个例子中去体会
请看下面的需求,假设有如下用户对象模型
public interface User {
public String getName();
public Date getRegisterDate();
public Customer getCustomer();
}
public interface Customer {
public String getId();
public String getName();
public boolean isVip();
}
public interface EntCustomer extends Customer {
public String getTrustId(); // 组织机构代码证号
}
对于给定的用户jack,且该用户所属客户是企业客户,那么我们如何获取该用户的姓名?如何获取用户所属客户的名称?如何判断该用户所属客户是否是VIP客户?如何取jack所属企业的组织机构代码证号?
* 采用java代码的方式,我们可以用如下的API调用得到所需信息:
jack.getName();
jack.getCustomer().getName();
jack.getCustomer().isVip();
((EntCustomer)jack.getCustomer()).getTrustId();
* 但我们现在在讲述OGNL,因此通过采用OGNL,我们可以用如下方式取得我们所需要的信息:
jack.name
jack.customer.name
jack.vip
jack.customer.trustId
由此我们可以看到OGNL的表达方式与java表达方式有以下几点不同:
** 不需关注对象类型,不需进行类型转换
** 表达方式更简短和直观
OGNL表达式最大的优点就是:*简单* 和 *直观*, 如果你觉得上面的表达式还不够简单和直观,那我们再来看:
name
这也是一个OGNL表达式,也就是取姓名!简单、直观了吧
了解了以上内容后,接下来我来看看它的基本概念
OGNL的两个最基本的概念:*表达式(expression)* 和 *上下文(context)*,
*表达式*。
OGNL就是表达式!它能让我们用简洁直观的语法表达我们的想法,如同上面的例子一般。简洁直观就是表达式的最大优点!我们知道表达式总是有一个结果,也就是说表达式总是会求值出一个结果,这个结果可能是一个字符串(如名称、组织机构代码证号等),或者是一个布尔值(如是否是VIP客户等),至于这个结果要怎么使用,那就是我们自己来决定的了。
*上下文(context)*
表达式的概念,我相信很好理解,但什么是上下文(context)?简单来说上下文就是环境,表达式求值的环境!还是不理解吗?我们来看一个例子:
还是上面最后那个例子:Java代码
name
细心的你是否会问,这个表达式要取谁的姓名呢?OK,很好!这就是环境,"谁"就存在于环境之中,也就是存在上下文之中。对于不同的环境/上下文,相同的表达式会有不同的结果!而环境/上下文的实质是什么呢?就是一组带名称的对象集合。
引用
思考:表达环境或上下文这个概念的最好的数据结构是什么?
OGNL上下文概念详解
我们前面说上下文就是一组名称-对象对的集合,如下图所示就是一个简单的上下文:
user ---> User(name:"jack", ...)
request ---> HttpServletRequest(header: ...)
那么在上面的环境中,我们可以有如下的OGNL表达式:
#user.name // 取用户的姓名
#user.age // 取用户年龄
#user.birthday // 取用户生日
#user.customer.name // 取用户所属客户的名称
#request.parameters // 取请求参数
请注意上面表达式中的"#user"和"#request"的用法,"#"表示访问环境/上下文中的对象。
现在可以很方便地访问环境中的对象了,那么如果你比较懒惰的话(记住:在程序员群体,懒惰是褒义词!),你是否觉得访问用户的姓名,年龄,生日,等等其它属性如果全部要使用"#user"来访问会不会太麻烦了呢?OK,ONGL的设计者早就考虑了这个问题,我们可以指定user为环境中的特权对象,访问该对象可以不需要使用#user的方式,如下所示代码与上面的完全等价,当然,前提是要预先指定user为特权对象:
name // 取用户的姓名
age // 取用户年龄
birthday // 取用户生日
customer.name // 取用户所属客户的名称
#request.parameters // 取请求参数
我们上面所说的"特权对象"在OGNL中称为"根对象"(root)
h3. 小结
综上所述,理解OGNL表达式的关键是理解其上下文的概念,因为OGNL的上下文概念中引入了"根对象"的概念,所以初学者往往会在这里迷失方向。
引用
OGNL的中文全称是对象图导航语言,也就是说OGNL是一门语言,如同java是一门语言一样。你是否会认为OGNL的作者太夸张了,竟敢把表达式谎称为语言?不,OGNL的语法确实非常简洁,OGNL的代码(我没有说表达式,因为代码是和语法相匹配的词语)通常不会换行,这意味着我们不可能把OGNL的代码写得很长,但是,这并不意味着OGNL的表达能力很弱。事实上,OGNL的语法设计非常简洁,但其功能却相当强大,如果你有兴趣,可以深入阅读OGNL参考手册的集合与lambda章节。
struts2中的OGNL上下文
struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:
|
|--request
|
|--application
|
context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]
|
|--session
|
|--attr
|
|--parameters
|--parameters
我们可以使用"#requet"访问HttpServletRequest对象, "#session"访问HttpSession对象,但请注意"根对象"是什么?是ValueStack!
那么ValueStack是什么?值栈。也就是一组对象的堆栈。也就是说,在struts2中,根对象不是我们通常的一个对象,而是一组对象。我们可以push新的对象到值栈中,也可以弹出值栈的栈顶对象。如上图所示,假设我们将user对象push到值栈中,那么如下的表达式将与之前我们见过的表达式一样,具有相同的结果:
name // 取用户的姓名
age // 取用户年龄
birthday // 取用户生日
customer.name // 取用户所属客户的名称
#request.parameters // 取请求参数
也就是说,我们使用name这个表达式的时候,ONGL会取"根对象"的name属性,但现在根对象是ValueStack!那么访问ValueStack的name属性意味着什么呢?这意味着: ValueStack会先查看栈顶元素是否有name属性,如果有就返回该属性值,否则取出栈顶下的元素,继续查看,直到栈底为止。
以上就是OGNL的核心概念,在struts2对OGNL中的上下文的概念又定义了新的含义,期待中...
以上文章为转载,作为参考希望\(^o^)/YES!
分享到:
相关推荐
深入讲解Struts中的ognl和valueStack
在Struts中,OGNL(Object-Graph Navigation Language)和Value Stack(VS)是两个核心概念,它们对于理解Struts的工作原理至关重要。 **OGNL:对象图导航语言** OGNL是一种强大的表达式语言,它允许在对象图中进行...
OGNL(Object-Graph Navigation Language)是一种基于 Java 的表达式语言,Struts2 框架中使用 OGNL 来访问和操作 ValueStack 中的对象。在 Struts2 中,OGNL 是一个强大的工具,允许开发者访问和操作 ValueStack 中...
在Struts2中,OGNL的核心组件之一是`ValueStack`,它充当了OGNL表达式的数据源。`ValueStack`是一个存储数据的栈结构,包含了所有的模型对象以及请求、会话和应用范围的数据。开发者可以通过EL表达式直接访问`...
在给定的压缩包文件“s20505_valueStack_OGNL”中,我们关注的核心知识点是Struts2中的OGNL(Object-Graph Navigation Language)和相关标签的使用。OGNL是Struts2默认的表达式语言,用于在视图层和控制器层之间传递...
OGNL通过ValueStack查找和操作对象。 - **ExpressionParser**:负责解析OGNL表达式,生成AST。 - **Context**:持有与表达式求值相关的环境信息,如变量、作用域等。 - **ObjectMapper**:负责对象与OGNL表达式...
在Struts2中,OGNL的执行环境由ValueStack提供。ValueStack是一个特殊的对象容器,它可以存储多个对象,并且支持通过OGNL表达式来访问这些对象。 - **ValueStack的作用**: - 作为OGNL的根对象,提供了一个统一的...
4. 使用`ValueStack`管理对象,避免过多的内存消耗。 总之,OGNL在Struts2.0中起着至关重要的作用,它极大地简化了数据绑定和视图渲染的过程,但同时也需要注意其潜在的安全风险。理解和熟练运用OGNL,将有助于提升...
2. **Ognl表达式**:ValueStack主要使用Object-Graph Navigation Language(OGNL)来访问和操作栈中的对象属性。OGNL是一种强大的表达式语言,允许动态地获取或设置对象的属性。 3. **ActionContext**:...
在 Struts2 中,OGNL 需要与 ValueStack 进行交互,以方便在 JSP 页面中直接通过 EL 方式访问 ValueStack 中的对象。ValueStack 是一个保存所有请求数据的对象栈,它包含了一个或多个根对象。 例如: - `${foo}` ...
camel-ognl-1.6.4.jar, camel-ognl-2.8.1.jar, com.springsource.org.ognl-2.6.9.jar, com.springsource.org.ognl-sources-2.6.9.jar, ognl-2.5.1.jar, ognl-2.6.11.jar, ognl-2.6.3.jar, ognl-2.6.5.jar, ognl-...
在这个主题中,我们将深入探讨OGNL(Object-Graph Navigation Language)以及如何通过`<s:property>`标签来访问Struts2中的值栈(Value Stack)。值栈是Struts2中一个核心的概念,它是一个存储用户请求数据和应用...
OGNL(Object-Graph Navigation Language)是一种强大的表达式语言,用于获取和设置Java对象的属性。它是Apache Struts2框架的核心组成部分,也被许多其他Java应用和框架广泛使用,如Spring WebFlow。在Java世界中,...
例如,了解`ValueStack`类如何解析和执行OGNL表达式,以及`OGNLContext`如何管理上下文变量,对于优化性能和解决调试问题都非常有帮助。 **工具支持** 开发过程中,有一些工具可以帮助我们调试和优化OGNL表达式,如...
开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12开发工具 ognl-3.1.12...
Action上下文中的ValueStack是存放Action实例和其它对象的地方,它支持OGNL表达式的查找和操作。 **OGNL标签的使用** 在Struts2中,OGNL标签允许我们在JSP页面上直接使用OGNL表达式来访问和显示数据。以下是一些...
5. **OGNL与Struts2的集成**:Struts2是如何将OGNL与Action、ValueStack和结果视图模板结合的。 6. **OGNL的异常处理**:遇到错误时,如何理解和解决OGNL表达式抛出的异常。 7. **最佳实践**:如何优化OGNL的使用...
赠送jar包:ognl-3.2.21.jar; 赠送原API文档:ognl-3.2.21-javadoc.jar; 赠送源代码:ognl-3.2.21-sources.jar; 赠送Maven依赖信息文件:ognl-3.2.21.pom; 包含翻译后的API文档:ognl-3.2.21-javadoc-API文档-...
OGNL(Object-Graph Navigation Language)是一种强大的表达式语言,常用于Java应用,特别是Struts2框架中,用于数据绑定和动态方法调用。在这个压缩包中,包含的是OGNL的源码和帮助文档,这对于深入理解OGNL的工作...
**表达式语言(EL)与OGNL概述** 表达式语言(EL)是用于在Java应用程序中简洁地访问和操作对象属性的一种方式。它允许开发者通过简单的语法来读取和设置对象的属性,调用方法,以及执行其他面向对象的操作。在Java EE...