一,什么是OGNL?
OGNL(Object Graph Navigation Language)--一种功能强大的表达式语言。能自动导航对象的结构和设置对象数据。
特点:
- 支持对象方法的调用
- 支持静态方法的调用
- 支持变量的赋值
- 支持操作集合语言
1.OGNL上下文
上篇文章提到过,ValueStack(值栈)的实现类是:OgnlValueStack类; OgnlValueStack包含了两个逻辑部分:对象栈(CompoundRoot,继承list接口)和OGNL上下文栈(OgnlContext,实现Map接口);在这个OgnlContext对象中,有一个默认的顶层对象root(引用),俗称root栈,下面一个对象称之为Map栈.
OGNL上下文是OGNL的核心对象,相当于一个Map容器。可以保存多个对象。通常情况下,标准的OGNL为设定一个根。上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。
3.OGNL基本操作
在Struts2框架中,当接受一个Action请求时,Struts2框架会创建一个ActionContext对象并实例化值栈等对象。由于OGNL 上下文作用于ActionContext对象,所以可以通过OGNL表达式可以获取ActionContext中所有对象。
(1)如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。例如:${user.name}。
(2)如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
- application对象:用于访问ServletContext,取值方法如:#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
- session对象:用来访问HttpSession,取值方法如:#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
- request对象:用来访问HttpServletRequest属性(attribute)的Map,取值方法如:#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
- parameters对象:用于访问HTTP的请求参数,取值方法如:#parameters.userName或者#parameters['userName']相当于调用request.getParameter("name")方法
- attr对象:如果不指定范围,其搜索范围按page->request->session->application顺序访问其属性,使用方法如:#attr.name或者#attr['name']。
- ?:获取满足指定条件的所有元素
- ^:获取满足指定条件的所有元素的第一个元素
- $:获取满足指定条件的所有元素的最后一个元素;
5.访问静态属性或方法
需要使用字符“@”进行标注,方法如下:
- @com.bean.Bean@NAME //相当于调用了Bean.NAME静态属性
- @com.bean.Bean@greeting() //相当于调用了Bean.greeting()静态方法
<constant nmae="struts.ognl.allowStaticMethodAccess" value="true"/>
6.访问数组
- 可以使用下标访问数组中指定的元素,例如: colors[0]
- 可以通过调用其 length 字段查出给定数组中有多少个元素,例如: colors.length
(1)List是一个有序集合,所以可以使用下标访问 List 中指定的元素,例如: list[0]
(2)Map以键值对方式进行存储。
- 可以通过获取Key的值来访问Value,例如:map.key 或 map['key']
- OGNL提供了获取Map对象的所有Key和Value的方法,它返回Key或Value的数组。map.keys--获取所有的key map.values--获取所有的 Value
- collection.isEmpty() 判断集合元素是否为空
- collection.size() 获取集合的长度
(1)投影:是对集合中列的操作,就是讲集合中某一列的数据抽取出来形成一个集合,这一列数据就是原集合中的投影
例如在一个集合中包含多个学生对象,获取这个集合中所有学生的姓名,操作:list.{name} (针对是值栈中的对象,如果是非值栈中的对象,需要加上“#”)
(2)选择:是对集合中行的操作,就是通过一定的条件获取集合中满足这一条件的数据,所获取的行就是对集合数据的选择操作。
例如在一个集合中包含多个学生对象,获取这个集合中学生年龄大于10的所有学生,操作:list.(?#this.age>10}(针对是值栈中的对象,如果是非值栈中的对象,需要加上“#”)
9.创建对象
OGNL支持直接使用表达式来创建对象。主要有三种情况:
- 构造List对象:使用{},中间使用','进行分割如{"aa", "bb", "cc"}
- 构造Map对象:使用#{},中间使用',进行分割键值对,键值对使用':'区分,如#{"key1" : "value1", "key2" : "value2"}
- 构造任意对象:直接使用已知的对象的构造方法进行构造。
10.OGNL比较重要的符号:
(1)“ % ”运算符
- 用%{}可以取出存在值堆栈中的Action对象,直接调用它的方法.
- 用途是在标识的属性为字符串类型时,计算OGNL表达式的值
<h3>构造Map</h3>
<s:set name="foo" value="#{'foo1':'b1', 'foo2':'b2'}" />
<p>The value of key "foo1" is <s:property value="#foo['foo1']" /></p>
<p>不使用%:<s:url value="#foo['foo1']" /></p>
<p>使用%:<s:url value="%{#foo['foo1']}" /></p>
运行结果为:
The value of key "foo1" is b1
不使用%:#foo['foo1']
使用%:b1
(2)"$"运算符
- 用于在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。
- 在Struts 2配置文件中,引用OGNL表达式
(3)“#”运算符(这个用法上面已经详细讲过)
- 访问根属性
- 进行投影或选择
- 构造Map集合