在讲解OGNL和标签库的时候,你必须了解Struts2的值栈
值栈(Value Stack)是Struts 2框架的核心概念
每次Action组件调用时,框架都会创建一个ValueStack对象,而且这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。 ValueStack像一个数据仓库,与web请求相关的所有数据都保存其中,包括Action本身。 web请求的处理过程中,Action组件,相关的拦截器都会访问其中的数据,也会把自己的处理结果存储其中,避免数据的大量传输及封装和拆装工作。
值栈分成两部分
ObjectStack 存储与请求处理相关的Action组件及对象。
Stack Context 存储本次请求相关的web运行环境信息,如应用上下文,会话和响应等。
值栈这种数据结构,所存储的内容有一定的规则,存取Struts2默认是使用OGNL表达式;值栈遵循栈的数据结构:先进后出;也就是栈的顶端是最近一次Action的信息;
看看值栈的内部结构:
值栈中内容会依据存入对象的不同,存储在不同的值对象中,上面说了值栈是一个数据仓库,既然这样我们如何利用这个丰富的仓库呢,Struts2默认使用便是OGNL表达式,这种表达式个人认为再好不过了,它可以在值栈中乱跑,去寻找你所需要的值;下面要讲一讲OGNL表达式了:
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,OGNL是一个开源项目,可以访问其官方站点www.ognl.org以获得源代码和相关资料。
OGNL是一种功能强大的EL(Expression Language,表达式语言),可以通过简单的表达式来访问Java对象中的属性。不是真正的编程语言,只是一种数据访问语言。
OGNL是Struts 2框架的默认表达式语言,增强了Struts 2的数据访问能力,同时简化了代码。
OGNL默认的根对象是值栈的ObjectStack。
直接访问 username user.name
索引访问 [1].name
OGNL如果要访问的对象不是根对象,则需要使用命名空间,用“#”来标识;
它是导航语言:我们就看看它的导航图:
利用此图,OGNL便可以找到它所找到的所有值;
简单介绍这张图中的对象:
parameters对象:用于访问http请求参数。
#parameters.foo或#parameters[‘foo’]用于返回调用HttpServletRequest的 getParameter(“foo”)方法的返回值
request对象:用户访问HttpServletRequest的属性
session对象、application对象、attr对象:该对象将以此搜素PageContext, HttpServletRequest,HttpSession,ServletContext对象中的属性
访问这些对象时需要使用#前缀指明
ognl的三种符号:
#:访问非根对象属性;
由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。
实际上,#相当于ActionContext. getContext();#session.msg表达式相当于
ActionContext.getContext().getSession(). getAttribute("msg")
用来构造Map,例如#{'foo1':'bar1', 'foo2':'bar2'}
用于过滤和投影(projecting)集合,如persons.{?#this.age>20}。
%:在标志的属性为字符串类型时,计算OGNL表达式的值。
$:在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码,
reg.ager=国际化资源信息:年龄必须在${min}同${max}之间;
在Struts 2框架的配置文件中引用OGNL表达式,例如校验器配置文件的<message>标签;
OGNL支持基本的Lambda表达式语法,可以在OGNL中使用一些简单的函数
语法格式:#方法名=:[方法体]
<s:property value="#isLessThanZero =:[#this < 0 ? 'true' : 'false'], #isLessThanZero(-1)"/>
Strust2的标签库的基础是基于OGNL表达式,所以,strust2的标签库与OGNL有着密切联系,他们无时无刻在一起。OGNL表达式的工作原理,了解即可,关键是在struts2标签的使用时候,明白OGNL的作用,便可以有的放矢;
这一篇是对值栈和OGNL的扫盲,有了这些基础,便可以使用Struts2的标签了,明白标签的实现原理,对下一篇标签的具体运用打下基础。