Ognl【Object-Graph Navigation language】它是一种功能强大的表达式语言(EL),可以存储对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能,它使用相同的表达式去存储对象的属性。
1.1. 应用场景
标签中:<s:property value="user.name" />
配置文件:<result type="redirect">/ma.jsp?name=${name}/>
1.2. 访问属性和方法
前台调用测试:
名字属性获取:<s:property value="user.username" />
地址对象中属性获取:
<s:property value="user.address.doornum" />
调用Action中的静态方法:
<s:property value="@com.sun.action.LoginAction@get()" />
其中类名必须书写全名,这样才能识别。
调用值栈中对象的普通方法[值栈中默认摆放的都是action对象]:
<s:property value="user.get()" />
调用JDK类的静态方法:
<s:property value="@java.lang.Math@floor(44.56)" />
上面的写法等同于<s:property value="@@floor(44.56)" />
Java.lang 类可以省略不写
注意:对于静态方法或静态属性的访问,切不可将属性或是方法设为private
调用普通类的静态属性
<s:property value="@com.sun.Address@doornum" />
注意:在重写构造器的时候,一定要保留一个空构造器
调用普通类的构造方法:
<s:property value="new com.sun.demo.Student('张山',24).name" />
获取action中的一个List集合:[集合中的数据以字符串的格式输出]
<s:property value="noteList" />
获取集合List中某个元素,可以通过下标索引:
<s:property value="noteList[2]" />
获取几个Set中的元素:
<s:property value="noteSet" />
注意:set集合中的元素是无序的且不能存放重复数据,所以不能通过下标索引的方式来获取,只有通过迭代器来获取
获取集合Map中的元素及某个指定元素:
<s:property value="noteMap" />
<s:property value="noteMap['note']" />
1.3. 集合的伪属性
OGNL能够引用集合的一些特殊属性,这些属性并不是javabean模式的,例如size(),length(),当表达式引用这些属性的时候,OGNL就会调用相应的方法,这就是伪属性。
Collection
Special properties
Collection
Size,isEmpty
List/Set
Iterator
Map
Key,values
Iterator
Next,hasNext
Enumeration
Next,hasNext,hasElement,hasMoreElements
使用Lambda表达式:
<s:property value="#f=:[#this==1?1:#this*#f(#this-1)],#f(4)" />
访问集合【投影,选择 ?^$】:
<s:property value="noteList" />
投影:
<s:property value="noteList.{title}" />
大括号相当于集合,类比于noteList集合中的所有title属性重新组成找一个列表,noteList中存放多个note对象。
<s:property value="noteList.{title}[0]" />
获取某一个日志的标题。
选择【可以获取各种条件下的结果】:
<s:property value="noteList.{#this.size > 100}" />
# 表示当前这个对象,该表达式的结果是显示各个对象是否符合条件,boolean值
<s:property value="noteList.{?#this.size > 100}" />
?表示取出所有符合条件的对象值
<s:property value="noteList.{?#this.size > 100}.{title}" />
<s:property value="noteList.{?#this.size > 100}.{title}[0]" />
获取第一个结果,不过存在数组下标越界的可能性,所以最好使用如下写法:
<s:property value="noteList.{^#this.size > 100}.{title}" />
^ 表示第一个元素
<s:property value="noteList.{$#this.size > 100}.{title}" />
$ 表示最后一个元素
1.4. OGNL中#的使用
# 可以取出堆栈上下文中存放的对象。
parameters
包含当前Http请求参数的Map
#parameters.id[0]相当于request.getParameter("id")
request
包含当前HttpServletRequest的属性的Map
#request.username 相当于request.getAttribute("username");
session
包含当前HttpSession的属性的Map
#session.username 相当于session.getAttribute("username");
application
包含当前ServletContext的属性的Map
#application.username 等同application.getAttribute("username");
attr
用于按作用域由小到大的顺序访问其属性
如:
<result type="redirect">
/test.jsp?username=zhangshan
</result>
页面重定向的时候传递参数,但是需要注意的是如果type为dispatcher,那么就不能够在访问的页面中传递参数了,当前这个也是没有必要那么做的。
在前台获取传递的参数的方式如下:
<s:property value="#parameters.username" />
注意:我们究竟应该使用哪个作用域来取值,希望大家还是能够有能力去区分,这样的话取值能够更加的准确。
1.5. OGNL中%的使用
用%{}可以取出存在于值栈中的Action对象,直接调用其方法。
例如:你的Action继承了ActionSupport,那么在页面的标签中,用%{getText(’key‘)}的方法可以拿出国际化信息。
1.6. OGNL中$的使用
用于在国际化资源文件中,引用OGNL表达式
在struts2的配置文件中,引用OGNL表达式
1.7. 值栈【valueStack】
值栈同其他几个作用域都存放在内存中,但是valueStack是根对象,不用写 # 来取值。这个对象贯穿整个Action【每个Action类的对象实例都会拥有一个valueStack】的生命周期,当struts2接受到一个action的请求后,会先去创建一个action对象的实例,但是并不会去调用action的方法,而是先将action类的相应属性放到其值栈对象的顶层节点【valueStack对象相当于一个栈】中。
查看内存中值栈信息:<s:debug></s:debug>
服务器跳转共用一个内存空间,在先后访问多个action时,被访问的action采用栈的存储方式进行压栈操作,访问属性时,从上向下进行查询搜索,有则获取,无则向下访问。
Top语法:
<s:property value="[1].top.age" />
取出第一个Action对象,然后取其属性
IN语法:
<s:property value="[1].age" />
取出第一个Action对象的某个属性,通常用来取属性
@语法:
调用Action中的静态方法:<s:property value="@vs@get()" /> 栈顶
vs=valueStack,取值栈对象
<s:property value="@vs1@get()" />
<s:property value="@vs2@get()" />
注意:当只有一个action时,vs就是vs1,而当有多个action时,vs1表示第一个action类,vs2就表示第二个action类,以此类推。
<!--EndFragment-->