OGNL(Object Graph Navigation Language)是一种强大的表达式语言,它能够自动导航对象的结构并访问和设置对象数据。在OGNL表达式中,它的核心对象为OGNL上下文。OGNL上下文相当于一个Map容器,在Map容器的Value中可以保存任何类型的数据(对象、数组等),通过OGNL上下文可以对容器中的对象导航。
如果获取User对象与Book对象中的name属性,可以使用以下表达式
#user.name
#book.name
OGNL表达式语言特点如下
*支持对象方法的调用
*支持静态方法的调用
*支持变量的赋值
*可以操作集合数据
二、Struts2框架中的OGNL
Struts2在OGNL的基础上进行了增强,提高了Struts对数据的访问能力。在Struts2中,ONGNL上下文作用于Strut2中的ActionContext对象。ActionContext对象是Struts2中的一个核心对象,它包含(值栈(根)、application、session、request、paramters、attr)
值栈符合于栈的基本特性,对象在栈中的存放是后进先出的,它由Strut2 API中的com.opensymphony.xowrk2.ognl.OgnlValueStrack类进行实现。ActionContext中包含了多个对象,值栈是ONGL上下文的根,值栈中的对象可以直接调用。
在Struts2中,当接受一个Action请求时,Strut会创建ActionContext对象并实例化值栈等对象。由于OGNL上下文作用于ActionContext对象,所以,通ONGL表达式可以获取ActionContext中的所有对象。
**获取值栈中的对象
${user.name}
**获取application中的对象
#application.name 或#application.['name']以上代码相当于application.getAtrribute("name")方法
**获取request中的对象
#request.name 或#request.['name']以上代码相当于requet.getAtrribute("name")方法
**获取session中的对象
#session.name 或session.['name']以上代码相当于session.getAttribute("name")方法
**获取parameters中的值
#parameters.name 或#parameters.['name']以上代码相当于request.getParameter("name")
**获取attr中的值
#attr.name 或#attr.['name']
三、操作普通的属性与方法
在Strut要2中使用ONGL表达式语言需要借助于Strut2标签进行输出。eg,获取User对象中的name,在JSP页面可以使用以下代码
<s:property value="user.id"/>
在OGNL表达式中,获取属性的方法主要有两种,除了上面介绍的方法外,也可以通过下面的代码进行。
<s;property value="user[id]"/>
OGNL不仅支持属性的调用,也支持方法调用
<s:property value="user.say()"/>
**通过OGNL操作普通属性与方法
(1)搭建环境
(2)创建名为Student的学生实体对象
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String say(){
return "我是一个学生";
}
}
(3)创建OGNLAction
public class OGNLAction extends ActionSupport {
//普通属性name
private String name;
//学生对象
private Student student;
//Map类型的request
Map<String,Object>request;
// 构造方法
public OGNLAction(){
// 实例化学生对象
student = new Student();
// 对学号赋值
student.setId(1);
// 对学生姓名赋值
student.setName("张三");
// 对name赋值
name = "tom";
// 获取Map类型的request
request = (Map<String, Object>) ActionContext.getContext().get("request");
}
// 请求处理方法
@Override
public String execute() throws Exception {
// 向request添加值
request.put("info", "request测试");
// 返回SUCCESS
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
(4)struts.xml
<struts>
<!-- 声明常量 -->
<constant name="struts.devMode" value="true"></constant>
<!-- 声明包 -->
<package name="myPackage" extends="struts-default">
<!-- 定义action -->
<action name="ognl" class="com.lyq.action.OGNLAction">
<!-- 结果映射 -->
<result name="success">success.jsp</result>
</action>
</package>
</struts>
(5)success.jsp
<body>
<div>
<h1>操作普通属性</h1>
属性name值:<s:property value="name"/>
<br/><hr>
学号:<s:property value="student.id"/>
<!--
也可以使用<s:property value="studet['id']"/>
-->
姓名:<s:property value="student.name"/><br/>
say()方法:<s:property value="student.say()"/>
<br><hr>
request中的info值:<s:property value="#request['info']"/>
</div>
</body>
由于request在ONGL的上下文中并不是根,所以输出request中的值需要加入“#”号,“#request['info']”输出request中的info值
四、访问静态方法与属性
Struts2的ONGL表达式支持对象的静态方法与静态属性的调用,需要使用字符“@”进行标注,其方式:
@com.lyq.bean.Bean@NAME
@com.lyq.bean.Bean@greeting()
Struts2默认不允许OGNL调用静态方法,要设置为:
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
关于Struts2的常量,可以查看Struts2核心jar包中的defalut.properties属性文件,得知其配置的默认值。
五、访问数组
eg,定义了一个名称为arr的数组,使用OGNL表达式的访问方法如下:
arr[0]
arr.length
六、访问List、Set、Map集合
**List集合
List集合是JDK API封装的一个无序集合对象,使用OGNG访问List集合,可以通过下值对其进行访问,其访问方式如下:
list[0]
**Set集合
Set集合是JDK API封装的一个无序集合对象,由于对象在Set集合中的存储方法无序,所以不能下标方式访问
**Map集合也是JDK API封装一个集合对象,它的数存储结构以key、Value方式进行存储。
map.key
map.values
collection.isEmpty
collection.size()
七、投影与选择
**投影
投影就是对集合的操作,就是指将集合中的某一列数据都抽取出来形成一个集合,这一列数据就是原集合中的投影。eg,一个集合中包含多个学生对象,获取这个集合中所有学生的姓名,就是投影操作。在OGNL表达式中通过如下代码实现
list.{name}
上述代码针对值栈中对象,如果是非值栈中的对象,还需要加上“#”号如“#list.name”。
**选择
选择是对集合中行的操作,就是通过一定的条件获取集合中满足这一条件的数据,所获取的行就是对集合中数据的选择操作
list.{?#htis.age>10}
上述代码针对值栈中对象,如果是非值栈中的对象,还需要加上“#”号如“#list.{?#this.age>10}”
**OGNL表达式中选择操作符及说明
?:获取满足指定条件的所有元素
^:获取满足指定条件的所有元素中的第一个元素
$:获取满足指定条件的所有元素中的最后一个元素