Struts2利用内建的OGNL(Obejct Graph Navigation Language)表达式语言的支持,大大加强了Struts2的数据访问功能,XWork在原有的OGNL基础上,增加了对ValueStack的支持。
在传统的OGNL表达式求值中,系统会假设只有一个“根”对象。下面是标准OGNL表达式求值,如果系统的Stack Context中包含两个对象:foo对象,它在Context中的名字为foo;bar对象,它在Context中的名字为bar,并将foo对象设置成Context的根对象。
#foo.blah //返回foo.getBlah( )的返回值
#bar.blah //返回bar.getBlah( )的返回值
blah //因为foo是根对象,所以默认返回foo.getBalh( )的返回值
通过上面的代码可以看出,OGNL表达式的语法非常简洁,如果有以下代码:
#bar.foo.blah
意味着返回bar.getFoo( ).getBlah( )的返回值。如果需要访问的属性属于根对象,则可以直接访问该属性,如blah;否则必须使用一个对象名作为前缀修饰该属性,如#bar.blah。
Struts2可以直接从对象中获取属性。Struts2提供了一个特殊的OGNL 属性访问器,它可以自动搜寻Stack Context的所有实体(从上到下),直到找到与求值表达式匹配的属性。
例如Stack Context中包含两个根实例:animal和person,这两个实例中包含“name”属性,而且animal还有一个“species”属性,而person有一个“salary”属性,其中animal是栈顶元素,而person实例在其后面。看下面的求值表达式:
species //返回animal.getSpecies()
salary //返回person.getSalary()
name //因为Struts2先找到animal实例,所以返回animal.getName()
如果实在需要取得person实例的name属性,必须通过如下代码:
#person.name
Struts2使用标准的Context来进行OGNL表达式语言求值,OGNL的顶级对象是一个Context,这个
Context对象就是一个Map类型实例,其根对象就是
ValueStack,如果需要访问ValueStack里的属性,直接通过${bar}即可。除此之外,Struts2还提供了一些命名对象,它们存在于
Stack Context中,所以访问这些对象时需要使用#前缀来指明。
命名对象 | 说明 |
parameters对象 | 用于访问HTTP请求参数。例如#parameters['foo']或#parameters.foo, 用于返回调用HttpServletRequest的getParameter("foo")的返回值。 |
request对象 | 用于访问HttpServletRequest的属性。例如#request['foo']或#request.foo, 用于返回调用HttpServletRequest的getAttribute("foo")的返回值。 |
session对象 | 用于访问HttpSession的属性。例如#session['foo']或#session.foo, 用于返回调用HttpSession的getAttribute("foo")的返回值。 |
application对象 | 用于访问ServletContext的属性。例如#application['foo']或#application.foo, 用于返回调用ServletContext的getAttribute("foo")的返回值。 |
attr对象 | 该对象将依次搜索如下对象:PageContext、HttpServletRequest、 HttpSession、ServletContext中的属性 |
Stack Context 和 ValueStack :
Stack Context是整个OGNL计算、求值的Context。
ValueStack只是Stack Context内的“根”对象而已。OGNL的Stack Context里除了包括ValueStack这个根之外,还包括parameters、request、session、application、attr等对象,但这些命名对象都不是根。
Stack Context里的“根”对象和普通命名对象的区别在于:
① 访问Stack Context里的命名对象需要在对象名之前添加#前缀
② 当访问OGNL的Stack Context里的“根”对象的属性时,可以省略对象名。