Struts2的OGNL表达式语言
OGNL是Object-GraphNavigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。
-
OGNL表达式的计算是围绕OGNL上下文进行的。OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
-
Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:propertyvalue="xxx"/>。
-
Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。
-
值栈(ValueStack) : 可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
-
调用ActionContext的put(key,value)放入的数据,需要使用#访问。
OGNL中重要的3个符号:#、%、$:
#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,需要时间的积累才渐渐弄清楚……
-
#符号
#符号的用途一般有三种。
-
访问非根对象属性,例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext(),如果访问的是根对象就不用使用“#”;#session.msg表达式相当于ActionContext.getContext().getSession().getAttribute("msg") 。
-
用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。
-
用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。
-
-
%符号
%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值,这个类似js中的eval,很暴力。用%{}可以取出存在值堆栈中的Action对象,直接调用它的方法.
例如你的Action如果继承了ActionSupport .那么在页面标签中,用%{getText('key')}的方式可以拿出国际化信息.
-
$符号
$符号主要有两个方面的用途。
-
在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。
-
在Struts 2框架的配置文件中引用OGNL表达式,例如:
<validators> <field name="intb"> <field-validator type="int"> <param name="min">10</param> <param name="max">100</param> <message>BAction-tes校验:数字必须为${min}为${max}之间!</message> </field-validator> </field> </validators>
-
使用#取出堆栈(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中的属性。也就是用于按request > session > application顺序访问其属性(attribute)。
OGNL中的集合操作
-
直接生成List类型集合的语法:{e1,e2,e3,e4...}
//直接生成一个List类型集合,该集合包含了3个元素:e1,e2,e3和e4。如果需要多个元素,则多个元素直接用英文逗号隔开;
-
自己生成Map类型集合的语法:#{key1:value1,key2:value2,...}
//直接生成一个Map类型的集合,该Map对象中每个key-value对象之间以英文冒号隔开。多项之间以英文逗号隔开;
-
OGNL提供了两个元素符:in 和 not in ,其中in判断某个元素是否在指定集合中;not in 判断是否不在某个集合中;
<s:if test=" 'name' in{'name','passwoed'} ">
"name"包含在集合里
</s:if>
<s:else>
"name"不在集合里
</s:else>
-
OGNL取得子集时有如下3个操作符:
? :取出所有符合选择逻辑的元素
^ :取出符合选择逻辑的第一个元素
$ :取出所有符合选择逻辑的最后一个元素
例如: person.relatives.{? #this.gender == 'male'}
在上面代码中,直接在集合后面紧跟 .{} 运算符表明用于取出该集合的子集,在{ }内使用?表明取出所有符合选择逻辑的元素,而 #tihs 代表集合里的元素。因此,上面代码的含义是:取出person的所有性别为male的relatives(亲戚)集合;
访问静态成员(包括调用静态方法、访问静态Field)
Struts2默认关闭了访问静态方法,打开方法:在struts.xml文件中增加如下代码片段:
<!--设置允许OGNL允许访问静态成员 -->
<constantname=”struts.ognl.allowStaticMethodAccess”value=”true”>
一旦设置了上面所示常量,OGNL表达式可以通过如下语法来访问静态成员:
@className@staticField
@className@staticMethod(val...)
JSP页面使用下面方式来访问静态Field和静态方法:
访问系统环境变量:
<s:propertyvalue=”@java.lang.System@getenv(‘JAVA_HOME’)”/><br/>
圆周率的值:<s:propertyvalue=”@java.lang.Math@PI”/>
Lambda表达式
格式::[…]
使用Lambda表达式计算阶乘: <s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br> |