`
jxb8901
  • 浏览: 166726 次
  • 性别: Icon_minigender_1
  • 来自: shenzhen
社区版块
存档分类
最新评论

OGNL & ValueStack 入门

    博客分类:
  • java
阅读更多
h1. 一个例子
请看下面的需求,假设有如下用户对象模型:
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表达式,也就是取姓名!简单吗?至少足够直观了吧:)

h1. 基本概念
我们前面看到了OGNL的一个最简单的例子,事实上OGNL确实很简单,如果能理解上面那个例子的用法,那么我们就掌握了OGNL的80%的用法了。
上面的例子虽然简单,但其中却含有OGNL的两个最基本的概念:*表达式(expression)* 和 *上下文(context)*,我们先看*表达式*。

h3. 表达式
OGNL就是表达式!它能让我们用简洁直观的语法表达我们的想法,如同上面的例子一般。简洁直观就是表达式的最大优点!我们知道表达式总是有一个结果,也就是说表达式总是会求值出一个结果,这个结果可能是一个字符串(如名称、组织机构代码证号等),或者是一个布尔值(如是否是VIP客户等),至于这个结果要怎么使用,那就是我们自己来决定的了。

h3. 上下文(context)
表达式的概念,我相信很好理解,但什么是上下文(context)?简单来说上下文就是环境,表达式求值的环境!还是不理解吗?我们来看一个例子:
还是上面最后那个例子:
name
细心的你是否会问,这个表达式要取谁的姓名呢?OK,很好!这就是环境,"谁"就存在于环境之中,也就是存在上下文之中。对于不同的环境/上下文,相同的表达式会有不同的结果!而环境/上下文的实质是什么呢?就是一组带名称的对象集合。
引用
思考:表达环境或上下文这个概念的最好的数据结构是什么?


h3. 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中的上下文的概念又定义了新的含义,且听我慢慢道来!

h3. struts2中的OGNL上下文
struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:
|
                     |--request
                     |
                     |--application
                     |
       context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]
                     |
                     |--session
                     |
                     |--attr
                     |
                     |--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表达式的核心概念,你理解了吗?下一步,你需要了进一步了解OGNL的语法,以发掘其更强大的功能!

分享到:
评论
15 楼 yangguo 2014-03-08  
  写得好啊,由使用的场景引出设计的原因,很透彻。
14 楼 workman93 2008-08-06  
谢谢楼主,好文章。
13 楼 lovemybook 2008-08-05  
项目中刚用到,学习学习!
12 楼 zhuyx808 2008-08-05  
通俗易懂,等待下篇的到来
11 楼 duanaiguo 2008-08-05  
官方文档的思维方式和国内程序员的思维还是有出入的,虽然照着写没问题,但是不看源码实现还是有不顺气的感觉,支持LZ,有时间可以再挖一下ValueStack的设计思路,这应该是一种比较通用的解决某类问题的方案,大家共同学习下。
10 楼 langyan666 2008-08-04  
学习。。。
9 楼 jxb8901 2008-08-04  
引用
很好的文章,希望LZ继续进行OGNL 的语法讲解。


谢谢各位的鼓励!

ognl的语法是很简单和简洁的,个人感觉看ognl的官方文档应该就足够了,自己要再写文章讲解也多半是重复照抄,没多大意思,呵呵。
8 楼 zhenjia 2008-08-04  
这个概念我喜欢 所以我才会爱上WEBWORK 以及WEBWORK的标签。
7 楼 java55 2008-08-04  
学习新知识了
6 楼 realghost819 2008-08-04  
flyeagle 写道
很好的文章,希望LZ继续进行OGNL 的语法讲解。

网银框架?网络框架?
文章很不错,言简意赅
希望能继续深入
5 楼 rz_wang 2008-08-04  
好文章,又重新复习了一下
4 楼 我很丑,但是我也不温柔 2008-08-04  
支持个。。。
3 楼 flyeagle 2008-08-04  
很好的文章,希望LZ继续进行OGNL 的语法讲解。
2 楼 netmil 2008-08-04  
恩.是的.
1 楼 miracle9i 2008-08-04  
嗯 很有启发性

相关推荐

    Struts2入门教程(全新完整版)

    四、OGNL与ValueStack(VS) 22 1.值栈入门 22 2.OGNL入门 24 3.普通方法访问 24 4.静态方法访问 24 5.默认类Math的访问 24 6.调用普通类的构造方法 25 7.集合对象初步 25 8.集合对象进阶 25 9.N语法top语法 26 10....

    Struts2 最基础快速入门

    这个"Struts2 最基础快速入门"教程是初学者学习该框架的理想起点。 首先,让我们深入了解Struts2的核心概念: 1. **Action类**:在Struts2中,业务逻辑主要由Action类执行。Action类是处理用户请求的中心组件,...

    达内培训机密资料_struts2_day02(2)

    根据提供的文件信息,我们可以归纳出以下相关...这些内容不仅涵盖了Struts2的基础概念,还涉及到了OGNL表达式的使用、ValueStack的管理以及分页功能的具体实现方法等,对于学习和实践Struts2都是非常有价值的参考资料。

    struts2从入门到精通总结(备忘)

    五、值栈(ValueStack) 值栈是Struts2的一个核心组件,用于存储和管理请求的模型数据。所有的Action实例都会被放入值栈,方便在视图层(JSP)直接访问。值栈也支持OGNL表达式,使得在JSP中可以方便地访问Action属性...

    十个struts入门程序源码

    8. **OGNL(Object-Graph Navigation Language)**:Struts 2默认使用OGNL作为表达式语言,用于在Action和视图之间绑定和访问数据。 9. **插件机制**:Struts 2支持丰富的插件,如Tiles插件用于布局管理,Struts2-...

    Struts 2.0从入门到精通(2)-源码

    - **ValueStack**:存储Action属性和OGNL表达式,使得视图可以直接通过OGNL访问Action的属性。 **3. OGNL(Object-Graph Navigation Language)** - OGNL是一种强大的表达式语言,用于在Java对象图中导航和操作数据...

    struts2入门教程

    Action中的属性会自动放入ValueStack,然后在JSP中通过OGNL表达式访问。 5. Freemarker模板引擎:Struts2默认使用Freemarker作为视图层模板技术,它允许开发者编写声明式的HTML,将业务逻辑与视图分离。 二、...

    struts2.0动画教程

    五、ValueStack与OGNL ValueStack是Struts2中用于存储Action属性和ActionContext的容器。OGNL(Object-Graph Navigation Language)是Struts2的默认表达式语言,用于在Action、ValueStack和View之间传递数据。开发者...

    个人觉得比较好的sturts2入门教程

    - **ValueStack**:存储Action上下文中的所有对象,便于在视图层通过OGNL访问。 **6. 视图技术** Struts2支持多种视图技术,如JSP、FreeMarker、Velocity等,可以根据项目需求选择合适的视图渲染方式。 **7. 配置...

    Struts入门到精通

    ### Struts 入门到精通 #### Struts简介 Struts是一个开源的、成熟的轻量级Web应用开发框架,主要用于构建企业级Java Web应用程序。它遵循Model-View-Controller(MVC)架构模式,能够清晰地分离数据模型、业务...

    struts2.0快速入门

    ### Struts2.0快速入门知识点详解 #### Struts2框架概述 - **定义与特点**:Struts2是一款基于MVC(Model-View-Controller)模式的Web应用程序框架,相较于Struts1.x版本有着根本性的变化。Struts2不仅吸取了...

    Struts2_入门篇_基本配置_通配符_参数注入_内置对象获取等。。。

    `ValueStack`用于管理Action和Ognl表达式之间的数据交换;`Session`则允许在用户会话间存储数据。 5. **Form表单处理**:在Struts2中,Form类通常对应于HTML表单,它封装了表单字段的数据。Action类可以引用Form类...

    在Java的Struts框架中ONGL表达式的基础使用入门

    在Struts2框架中,ActionContext被设置为OGNL的上下文,值栈(ValueStack)作为根对象。值栈是一个存储Action实例和相关数据的结构,它使得在栈顶的Action实例的属性可以直接通过OGNL表达式访问,无需添加#前缀。...

    浪曦Struts2应用开发系列ppt

    Struts2的核心概念包括Action、Result、Interceptor(拦截器)、ValueStack(值栈)和OGNL(对象-图形导航语言)。Action是处理用户请求的业务逻辑组件,Result负责转发或重定向到相应的视图。Interceptor在Action...

    Struts.chm

    接着,深入学习Struts 2的特性,如拦截器、ValueStack和OGNL表达式,以及如何集成其他框架如Hibernate和Spring,将有助于提升Web开发能力。 **进一步阅读**: 提供的两个.chm文件,"Struts2.chm"和"Struts1.3.chm...

    xwork2.0源代码,理解struts2

    8. **ValueStack**: 用于存储Action的属性,提供了一种Ognl表达式(Object-Graph Navigation Language)的访问方式,方便在视图层和模型层之间传递数据。 通过阅读XWork源代码,我们可以了解到这些组件如何协同工作...

    webwork入门简介

    3. **OGNL(Object Graphical Navigation Language)**:这是一种强大的表达式语言,允许动态地遍历对象图表并执行方法。通过ValueStack,开发者可以透明地访问多个Bean的属性,增强了代码的简洁性和可读性。 4. **...

Global site tag (gtag.js) - Google Analytics