%的作用
标签的属性为字符串类型时,仍然计算OGNL表达式的值。
如果标签属性本来就是ognl表达式,则没有用。
< s:url value ="%{#foobar['foo1']}" />
因为value的属性本来是string,也就是里面写的是什么就显示什么。
如果用%{},那么{}里面的就会被当作ognl语言来运行了。
8.2 Struts 2的OGNL
OGNL是Struts 2框架的默认表达式语言,增强了Struts 2的数据访问能力,同时简化了代码。
8.2.1 Struts 2的OGNL表达式
标准的OGNL会设定一个根对象(root对象)。假设使用标准OGNL表达式来求值(不使用Struts 2的OGNL表达式),如果OGNL上下文(OgnlContext Map类型)有两个对象:foo对象,在OgnlContext中名称为foo;bar对象,在OgnlContext中名称为bar。同时foo对象被设置为根对象(root)。则利用下面的OGNL表达式求值:
// 返回foo.getBlah() #foo.blah //返回bar.getBlah() #bar.blah //返回foo.getBlah() ,因为foo为根对象 blah |
★ 说明 ★
使用OGNL是非常简单的,如果要访问的对象不是根对象,如示例中的bar对象,则需要使用命名空间,用“#”来标识,如“#bar”;如果访问一个根对象,则不用指定命名空间,可以直接访问根对象的属性。
在Struts 2框架中,值栈(Value Stack)就是OGNL的根对象,假设值栈中存在两个对对象实例:Man和Animal,这两个对象实例都有一个name属性,Animal有一个 species属性,Man有一个salary属性,假设Animal在值栈的顶部,Man在Animal后面,下面的代码片断会帮助读者更好地理解 OGNL表达式:
// 调用animal.getSpecies() species // 调用man.getSalary() salary // 调用animal.getName(),因为Animal位于值栈的顶部 name |
最后一行示例代码,返回的是animal.getName()返回值,即返回了Animal的name属性,因为Animal是值栈的顶部元素,OGNL将从顶部元素搜索,所以会返回Animal的name属性值。如果要获得Man的name值,则需要如下代码:
man.name |
Struts 2允许在值栈中使用索引,示例代码如下所示:
[0].name // 调用animal.getName() [1].name // 调用man.getName() |
★ 注意 ★
使用索引,并不是直接获得指定的元素,而是从指定的索引位置搜索。
Struts 2中的OGNL Context是ActionContext,如图8.2所示。
图8.2 Struts 2的OGNL Context结构示意图 |
★ 说明 ★
图8.2只是说明Struts 2的OGNL Context结构,实际上Context还包含其他对象。
由于值栈是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,则可以直接通过下面的代码访问值栈中的属性:
//获得值栈中的foo属性 ${foo} |
如果访问其他Context中的对象,由于不是根对象,在访问时,需要加#前缀。
application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用Servlet的getAttribute("username")。
session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
request 对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.get力Attribute ("userName")。
parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
attr对象:用于按page-request-session-application顺序访问其属性。