- 浏览: 1529630 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (516)
- Java (49)
- Java/Struts 2.0 (25)
- Java/Spring、Spring MVC (11)
- Java/Quartz (3)
- Java/Lucene (6)
- Java/Hibernate (19)
- Java/openJPA (7)
- Java/DWR (7)
- Java/Security、Spring Security/OAuth2 (6)
- Java/Threading (9)
- Java/XML (22)
- java/design pattern (4)
- Android (2)
- JavaScript (46)
- jquery (3)
- DB/MySQL (23)
- DB/Oracle (16)
- PHP (25)
- CSS (20)
- Linux (38)
- C/C++、DLL、Makefile、VC++ (31)
- 正则 (9)
- Eclipse (4)
- 安全、网络等概念 (25)
- 集群 (7)
- 网页 (5)
- 视频\音频 (1)
- HTML (6)
- 计算机数学/算法 (3)
- Virtualbox (1)
- LDAP (2)
- 数据挖掘 (6)
- 工具破解 (1)
- 其他 (13)
- Mail (1)
- 药材 (3)
- 游戏 (2)
- hadoop (13)
- 压力测试 (3)
- 设计模式 (3)
- java/Swing (2)
- 缓存/Memcache (0)
- 缓存/Redis (1)
- OSGI (2)
- OSGI/Gemini (0)
- 文档写作 (0)
- java/Servlet (3)
- MQ/RabbitMQ (2)
- MQ/RocketMQ (0)
- MQ/Kafka (1)
- maven (0)
- SYS/linux (1)
- cache/redis (1)
- DB/Mongodb (2)
- nginx (1)
- postman (1)
- 操作系统/ubuntu (1)
- golang (1)
- dubbo (1)
- 技术管理岗位 (0)
- mybatis-plus (0)
最新评论
-
pgx89112:
大神,请赐我一份这个示例的项目代码吧,万分感谢,1530259 ...
spring的rabbitmq配置 -
string2020:
不使用增强器 怎么弄?
OpenJPA的增强器 -
孟江波:
学习了,楼主,能否提供一份源代码啊,学习一下,十分感谢!!!4 ...
spring的rabbitmq配置 -
eachgray:
...
spring-data-redis配置事务 -
qljoeli:
学习了,楼主,能否提供一份源代码啊,学习一下,十分感谢!!!1 ...
spring的rabbitmq配置
OGNL —— 完美的催化剂
为了解决数据从View层传递到Controller层时的不匹配性,Struts2采纳了XWork的OGNL方案。并且在OGNL的基础上,构建了OGNLValueStack的机制,从而比较完美的解决了数据流转中的不匹配性。OGNL(Object Graph Navigation Language),是一种表达式语言。使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性、调用Java对象树的方法、同时能够自动实现必要的类型转化。如果我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。
如何使用OGNL
让我们先研究一下OGNL的API,他来自于Ognl的静态方法:
Java代码
1. 2. 3.public static Object getValue( Object tree, Map context, Object root ) throws OgnlException; 4. 5. 6.public static void setValue( Object tree, Map context, Object root, Object value ) throws OgnlException
我们可以看到,OGNL的API其实相当简单,你可以通过传递三个参数来实现OGNL的一切操作。而这三个参数,被我称为OGNL的三要素。
简单的API,就已经能够完成对各种对象树的读取和设值工作了。这也体现出OGNL的学习成本非常低。
在上面的测试用例中,需要特别强调进行区分的,是在针对不同内容进行取值或者设值时,OGNL表达式的不同。
Struts2 Reference 写道
The framework uses a standard naming context to evaluate OGNL expressions. The top level object dealing with OGNL is a Map (usually referred as a context map or context). OGNL has a notion of there being a root (or default) object within the context. In expression, the properties of the root object can be referenced without any special "marker" notion. References to other objects are marked with a pound sign (#).
上面这段内容摘自Struts2的Reference,我把这段话总结为以下2条规则:
A) 针对根对象(Root Object)的操作,表达式是自根对象到被访问对象的某个链式操作的字符串表示。
B)针对上下文环境(Context)的操作,表达式是自上下文环境(Context)到被访问对象的某个链式操作的字符串表示,但是必须在这个字符串的前面加上#符号,以表示与访问根对象的区别。
上面的这点区别咋看起来非常容易理解,不过一旦放到特定的环境中,就会显示出其重要性,它可以解释很多Struts2在页面展示上取值的各种复杂的表达式的现象。这一点在下一篇文章中会进行具体的分析。
OGNL三要素
我把传入OGNL的API的三个参数,称之为OGNL的三要素。OGNL的操作实际上就是围绕着这三个参数而进行的。
1. 表达式(Expression)
表达式是整个OGNL的核心,所有的OGNL操作都是针对表达式的解析后进行的。表达式会规定此次OGNL操作到底要干什么。
我们可以看到,在上面的测试中,name、department.name等都是表达式,表示取name或者department中的name的值。OGNL支持很多类型的表达式,之后我们会看到更多。
2. 根对象(Root Object)
根对象可以理解为OGNL的操作对象。在表达式规定了“干什么”以后,你还需要指定到底“对谁干”。
在上面的测试代码中,user就是根对象。这就意味着,我们需要对user这个对象去取name这个属性的值(对user这个对象去设置其中的department中的name属性值)。
3. 上下文环境(Context)
有了表达式和根对象,我们实际上已经可以使用OGNL的基本功能。例如,根据表达式对根对象进行取值或者设值工作。不过实际上,在OGNL的内部,所有的操作都会在一个特定的环境中运行,这个环境就是OGNL的上下文环境(Context)。说得再明白一些,就是这个上下文环境(Context),将规定OGNL的操作“在哪里干”。
OGNL的上下文环境是一个Map结构,称之为OgnlContext。上面我们提到的根对象(Root Object),事实上也会被加入到上下文环境中去,并且这将作为一个特殊的变量进行处理,具体就表现为针对根对象(Root Object)的存取操作的表达式是不需要增加#符号进行区分的。
OgnlContext不仅提供了OGNL的运行环境。在这其中,我们还能设置一些自定义的parameter到Context中,以便我们在进行 OGNL操作的时候能够方便的使用这些parameter。不过正如我们上面反复强调的,我们在访问这些parameter时,需要使用#作为前缀才能进行。
OGNL与模板
我们在尝试了OGNL的基本操作并了解了OGNL的三要素之后,或许很容易把OGNL的操作与模板联系起来进行比较。在很多方面,他们也的确有着相似之处。对于模板,会有一些普通的输出元素,也有一些模板语言特殊的符号构成的元素,这些元素一旦与具体的Java对象融合起来,就会得到我们需要的输出结果。
而OGNL看起来也是非常的类似,OGNL中的表达式就雷同于模板语言的特殊符号,目的是针对某些Java对象进行存取。而OGNL与模板都将数据与展现分开,将数据放到某个特定的地方,具体来说,就是Java对象。只是OGNL与模板的语法结构不完全相同而已。
深入浅出OGNL
在了解了OGNL的API和基本操作以后,我们来深入到OGNL的内部来看看,挖掘一些更加深入的知识。
OGNL表达式
OGNL支持各种纷繁复杂的表达式。但是最最基本的表达式的原型,是将对象的引用值用点串联起来,从左到右,每一次表达式计算返回的结果成为当前对象,后面部分接着在当前对象上进行计算,一直到全部表达式计算完成,返回最后得到的对象。OGNL则针对这条基本原则进行不断的扩充,从而使之支持对象树、数组、容器的访问,甚至是类似SQL中的投影选择等操作。
接下来我们就来看看一些常用的OGNL表达式:
1. 基本对象树的访问
对象树的访问就是通过使用点号将对象的引用串联起来进行。
例如:name,department.name,user.department.factory.manager.name
2. 对容器变量的访问
对容器变量的访问,通过#符号加上表达式进行。
例如:#name,#department.name,#user.department.factory.manager.name
3. 使用操作符号
OGNL表达式中能使用的操作符基本跟Java里的操作符一样,除了能使用 +, -, *, /, ++, --, ==, !=, = 等操作符之外,还能使用 mod, in, not in等。
4. 容器、数组、对象
OGNL支持对数组和ArrayList等容器的顺序访问:
例如:group.users[0]
同时,OGNL支持对Map的按键值查找:
例如:#session['mySessionPropKey']
不仅如此,OGNL还支持容器的构造的表达式:
例如:{"green", "red", "blue"}构造一个List,#{"key1" : "value1", "key2" : "value2", "key3" : "value3"}构造一个Map
你也可以通过任意类对象的构造函数进行对象新建:
例如:new java.net.URL("http://localhost/")
5. 对静态方法或变量的访问
要引用类的静态方法和字段,他们的表达方式是一样的@class@member或者@class@method(args):
例如:@com.javaeye.core.Resource@ENABLE,@com.javaeye.core.Resource@getAllResources
6. 方法调用
直接通过类似Java的方法调用方式进行,你甚至可以传递参数:
例如:user.getName(),group.users.size(),group.containsUser(#requestUser)
7. 投影和选择
OGNL支持类似数据库中的投影(projection) 和选择(selection)。
投影就是选出集合中每个元素的相同属性组成新的集合,类似于关系数据库的字段操作。投影操作语法为 collection.{XXX},其中XXX 是这个集合中每个元素的公共属性。
例如:group.userList.{username}将获得某个group中的所有user的name的列表。
选择就是过滤满足selection 条件的集合元素,类似于关系数据库的纪录操作。选择操作的语法为:collection.{X YYY},其中X 是一个选择操作符,后面则是选择用的逻辑表达式。而选择操作符有三种:
? 选择满足条件的所有元素
^ 选择满足条件的第一个元素
$ 选择满足条件的最后一个元素
例如:group.userList.{? #this.name != null}将获得某个group中user的name不为空的user的列表。
上述的所有的表达式,只是对OGNL所有表达式的大概的一个概括,除此之外,OGNL还有更多的表达式,例如lamba表达式等等。最具体的表达式的文档,大家可以参考OGNL自带的文档:
http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/apa.html
在撰写时,我也参考了potain同学的XWork教程以及一些网络上的一些文章,特此列出:
http://www.lifevv.com/java/doc/20071018173750030.html
http://blog.csdn.net/ice_fire2008/archive/2008/05/12/2438817.aspx
OGNLContext
OGNLContext就是OGNL的运行上下文环境。OGNLContext其实是一个Map结构,如果查看一下它的源码,就会发现,它其实实现了 java.utils.Map的接口。当你在调用OGNL的取值或者设值的方法时,你可能会自己定义一个Context,并且将它传递给方法。事实上,你所传递进去的这个Context,会在OGNL内部被转化成OGNLContext,而你传递进去的所有的键值对,也会被OGNLContext接管维护,这里有点类似一个装饰器,向你屏蔽了一些其内部的实现机理。
在OGNLContext的内部维护的东西很多,其中,我挑选2个比较重要的提一下。一个是你在调用方法时传入的Context,它会被维护在OGNL内部,并且作为存取变量的基础依据。另外一个,是在Context内部维护了一个key为root的值,它将规定在OGNLContext进行计算时,哪个元素被指定为根对象。其在进行存取时,将会被特殊对待。
this指针
我们知道,OGNL表达式是以点进行串联的一个字符串链式表达式。而这个表达式在进行计算的时候,从左到右,每一次表达式计算返回的结果成为当前对象,并继续进行计算,直到得到计算结果。每次计算的中间对象都会放在一个叫做this的变量里面这个this变量就称之为this指针。
例如:group.userList.size().(#this+1).toString()
在这个例子中,#this其实就是group.userList.size()的计算结构。
使用this指针,我们就可以在OGNL表达式中进行一些简单的计算,从而完成我们的计算逻辑,而this指针在lamba表达式的引用中尤为广泛,有兴趣的读者可以深入研究OGNL自带的文档中lamba表达式的章节。
默认行为和类型转化
在我们所讲述的所有的OGNL的操作中,实际上,全部都忽略了OGNL内部帮助你完成的很多默认行为和类型转化方面的工作。
我们来看一下OGNL在进行操作初始化时候的一个函数签名:
1. 2.public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context ); 可以看到,在初始化时,OGNL还需要额外初始化一个类型转化的接口和一些其他的信息。只不过这些默认行为,由OGNL的内部屏蔽了。
一旦需要自己定义针对某个特定类型的类型转化方式,你就需要实现TypeConverter接口,并且在OGNL中进行注册。
同时,如果需要对OGNL的许多默认行为做出改变,则需要通过设置OGNL的全局环境变量进行。
发表评论
-
Struts2 (Json) + jQuery 组合的简单用法
2011-03-01 23:02 10381、将struts2的json插件加入web工程的lib,js ... -
Struts2中$,#,%的区别
2011-03-01 22:57 1386转自:http://hi.baidu.com/di ... -
<s:generator>
2011-02-27 21:54 1431<s:generator val="%{'aa ... -
<s:merge>
2011-02-27 21:45 896<s:set var="americanCar ... -
<s:append>
2011-02-27 21:44 1258<s:set var="list1" ... -
<s:iterator>
2011-02-27 21:01 1400属性名称 必填项 默认值 ... -
<s:bean>
2011-02-27 18:32 958public class DegreeConverter { ... -
<s:param>
2011-02-27 18:21 3611param标签用来把一个参数传递给包含着它的那个标签。 不管 ... -
updownselect
2011-02-27 16:24 1408<s:updownselect name="c ... -
combobox
2011-02-27 16:08 966<s:combobox name="combo ... -
checkboxlist
2011-02-27 12:15 899ddd public class LoginAction ... -
select optgroup
2011-02-27 11:58 725代码片段: public class LoginAction ... -
select标签
2011-02-23 21:17 1029import com.opensymphony.xwork2. ... -
radio标签
2011-02-23 21:13 1017import java.util.SortedMap; ... -
list、listkey、listValue属性
2011-02-22 21:07 7259list、listKey、listValue属性对 ... -
Ongl 与 ValueStack ActionContext
2011-01-09 21:03 1481转自:http://blog.sina.com.c ... -
关于Struts2.0 标签中采用%{} 的处理原理
2011-01-09 20:57 1597项目中采用struts2.0时,常常使用计算表单式的处理源码 ... -
struts2 tags
2010-01-08 13:22 12351.<s:property> propert ... -
Struts2和Freemarker整合应用批量静态页面的生成
2009-11-07 23:19 3870利用Struts2生成静态页面其实很灵活,很强大,尤其是利用S ... -
导致"ERROR - Could not find action or result"的可能原因。
2009-10-08 10:51 2171在某些情况Struts 2.x的一些错误消息提示让人看得琢磨不 ...
相关推荐
2. **AST节点(Abstract Syntax Tree Nodes)**:这些是解析过程的产物,每个节点代表OGNL表达式的一部分,如对象引用、属性访问或方法调用。 3. **值解析器(ValueResolver)**:负责实际的对象属性访问和方法调用...
Struts2.0是Apache软件基金会的一个开源项目,它是一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架。在Struts2中,OGNL(Object-Graph Navigation Language)是一种强大的表达式语言,用于获取...
1. **OGNL(Object-Graph Navigation Language)**:介绍Struts2中使用的表达式语言,用于在Action和视图之间传递数据。 2. **Action与Result**:详细阐述Action类的设计和编写,以及如何定义Result来控制流程跳转...
4. **OGNL表达式语言**:Struts2.0使用OGNL(Object-Graph Navigation Language)作为默认的数据绑定和表达式语言,它使得数据操作更为简单。 5. **插件架构**:Struts2.0具有丰富的插件支持,如文件上传、日期时间...
OGNL(Object-Graph Navigation Language)则是Struts2中的表达式语言,用于在视图和模型之间传递数据。此外,Struts2还支持自定义拦截器、过滤器Dispatcher和插件机制,这大大增强了框架的可扩展性和灵活性。 在...
Struts2.0是Java Web开发中非常重要的一个MVC框架,它是在原有的Struts1.x基础上进行改进和发展而来的。这个"三大框架中文文档中的struts2.0开发手册"为程序员提供了一份详尽的参考资料,帮助他们理解和掌握Struts...
- **OGNL表达式**:OGNL作为默认的表达式语言,用于在Action和视图之间传递数据。 - **插件系统**:允许轻松扩展框架功能,如RESTful支持、JSON输出等。 了解以上基本概念后,你可以通过创建简单的示例项目来实践...
Struts2.0是一款强大的Java Web框架,它在MVC(Model-View-Controller)设计模式的基础上,提供了灵活且强大的架构来构建企业级的Web应用程序。这个“Struts2.0 Jar包”包含了所有必要的库文件,使得开发者可以便捷...
十一、Struts2.0与OGNL表达式语言 OGNL(Object-Graph Navigation Language)是Struts2.0中的一种强大且灵活的表达式语言,它用于访问和操作对象图。通过OGNL,开发者可以方便地获取对象属性,执行方法调用,以及...
在JSP页面中,可以直接使用OGNL表达式访问Action中的属性。 4. **拦截器**:拦截器是Struts2的一大特色,它允许你在Action执行前后插入自定义逻辑。常见的拦截器有验证、日志、性能监控等。 5. **结果类型**:定义...
Struts 2.0使用OGNL作为默认表达式语言,用于在Action与视图之间传递数据。OGNL提供强大的数据访问和操作能力,可以在JSP页面上直接访问Action中的属性。 7. **Tiles插件** Tiles是Struts 2.0的一个视图组件,它...
Struts2.0是Java Web开发中一个非常重要的框架,它是Apache软件基金会的Jakarta项目下的一...随着深入学习,你将能够掌握更多高级特性,如拦截器的自定义、动态方法调用、OGNL表达式等,从而更高效地开发Java Web应用。
3. **OGNL(Object-Graph Navigation Language)**: OGNL是Struts 2.0中用于表达式语言,用于在Action和视图之间传递数据。通过OGNL,开发者可以方便地访问和修改对象属性,使得数据绑定更为简洁。 4. **配置方式**...
Struts2.0是一个强大的Java Web应用程序框架,它基于Model-View-Controller(MVC)设计模式,旨在简化企业级应用的开发流程。这个压缩包包含的是Struts2.0的核心库和其他必要的JAR文件,这些文件对于创建一个基于...
视图层通常使用JSP或FreeMarker模板技术,结合OGNL表达式来展示数据。此外,还可以集成Spring框架进行依赖注入,增强系统的可测试性和解耦性。 五、入门学习资源 "Struts2.0入门学习资料"可能包含教程文档、示例...
例如,在JSP中可以直接用OGNL表达式访问Action的属性。 6. **Freemarker或JSP作为视图**:Struts2.0支持使用Freemarker或JSP作为视图技术,用于生成动态HTML页面。开发者可以通过模板语言来控制页面布局和数据展示...
通过学习这个系列,你可以掌握如何创建Struts2.0的项目结构,编写Action类,配置Action和Result,使用Interceptor实现业务逻辑的增强,以及如何在JSP页面中利用Ognl表达式展示数据。此外,还将了解如何结合其他Java ...
Struts2.0是一款强大的Java Web开发框架,它极大地简化了MVC(Model-View-Controller)应用的构建。在Struts2中,标签库是其核心特性之一,提供了丰富的功能,使得开发者能够更高效地编写视图层代码。本文档主要针对...
6. **OGNL(Object-Graph Navigation Language)**:介绍Struts2.0中使用的表达式语言OGNL,用于数据绑定、属性访问和方法调用,以及在JSP页面中的使用。 7. **国际化与异常处理**:讲解如何实现多语言支持,以及...
理解每个JAR的作用对于有效地利用Struts2框架进行开发至关重要,这包括了解如何配置Action、编写Interceptor、处理表单提交、利用OGNL表达式以及与视图技术如FreeMarker或JSP的集成。 在实际开发中,根据项目需求,...