
4.2 Struts 2的OGNL表达式与应用案例
OGNL是Object-Graph Navigation Language的缩写,是一种功能强大的表达式语言。通过简单的表达式语法,可以存取对象的任意属性值,也可以调用对象的方法等功能。OGNL通常与Struts 2标签绑定使用。
提示:OGNL表达式类似于EL表达式,其使用方式也类似。
在JSP页面上可以利用OGNL访问到值栈(ValueStack)里的对象属性。若希望访问值栈中ContextMap中的数据,需要给OGNL表达式加上一个前缀字符#,如果没有前缀字符#,搜索将在ObjectStack中进行。
1.读取ObjectStack里的对象的属性
若想访问Object Stack里的某个对象的属性,可以使用以下几种形式之一。
object.propertyName或object['propertyName']或object["propertyName"]
【例4-1】本例展示了Struts 2是如何存储数据,以及如何访问数据的。
首先定义一个模型Person,然后在Action中定义、创建其对象并赋值,最后在页面中显示该对象的值。
1)设计模型类Person,其代码如下。
package com.edu.ognl.action; import java.util.Date; public class Person { private String name; private int age; private Date birthday; public Person() {} public Person(String name, int age, Date birthday) { this.name = name; this.age = age; this.birthday = birthday; } //省略了getter/setter方法 }
2)设计Action,并配置Action,其代码如下。

3)设计显示信息的JSP页面(showognl.jsp),其代码如下。

4)启动服务器,并在地址栏中输入下列网址。

其运行界面如图4-2所示。

图4-2 【例4-1】的运行界面
2.读取ContextMap里的对象的属性
若访问ContextMap里某个对象的属性,需要给表达式加上一个前缀字符#,其访问形式可以是下列形式之一。
#object.propertyName或 #object['propertyName']或 #object["propertyName"]
【例4-2】在Action中,给Web对象request、session和application等提供值,然后在页面中获取并显示。
【设计与实现】
1)设计Action: OgnlAction,并采用注释配置Action,其代码如下。
package com.edu.ognl.action; //省略了import; @Namespace("/test") @ParentPackage("struts-default") @Results({ @Result(name = "success", location = "/showognl.jsp")}) public class OgnlAction extends ActionSupport { @Action("ognlTest") public String ognlTest() throws Exception { // 获得ActionContext实例,以便访问Servlet API ActionContext ctx = ActionContext.getContext(); ctx.getApplication().put("msg", "application信息"); //存入到application ctx.getSession().put("msg", "seesion信息"); //保存到session HttpServletRequest request = ServletActionContext.getRequest(); //获取request对象 request.setAttribute("msg", "request信息"); // 保存到request return SUCCESS; } }
2)设计显示信息的JSP页面(showognl.jsp),其代码如下。

3)启动服务器,并在地址栏中输入下列网址。

其运行界面如图4-3所示。

图4-3 【例4-2】的运行界面
3.访问数组、List和Map类型的属性
利用OGNL可以访问集合(例如,List对象、Map对象或数组对象)类型对象中的数据元素。
(1)访问数组和List类型的对象
对数组对象和List类型对象的访问,其访问格式是一样的,都是使用从零开始的数字索引的形式,同时也可以调用数组和List类型对象上的方法。
OGNL中使用List对象格式如下。
{e1, e2, e3, …}
该表达式直接生成一个List对象,该List对象中包含:e1、e2、e3…等元素。
(2)访问Map类型对象
访问Map类型对象中的对象时需要将Map中的key作为索引或者将key作为属性的方式访问,将返回与该key所对应的value。
OGNL中使用Map对象格式如下。
#{key1:value1, key2:value2, key3:value3, …}
(3)OGNL集合可以使用in和not in判定元素是否属于该集合
● in:表达式用来判断某个元素是否在指定的集合对象中。
● not in:用于判断某个元素是否不在指定的集合对象中。
例如,基于Struts 2标签,利用OGNL运算,判断元素a是否属于集合{'a', 'b'}。
<s:if test="'a' in {'a', 'b'}">…</s:if>
(4)OGNL还可以使用某些规则获取集合对象的子集
常用的相关操作如下。
● ? :用于获取多个符合逻辑的元素。
● ∧:用于获取符合逻辑的第一个元素。
● $:用于获取符合逻辑的最后一个元素。
如下面的代码所示。
Student.sex{? #this.sex= ='male'}//获取Student的所有male的sex集合
【例4-3】本例展示了如何创建Map和List对象,并显示其信息。设计一个JSP页面,在该页面内生成OGNL的Map和List对象,并显示其信息。
【设计与实现】
1)设计的JSP页面,其代码如下。

2)启动服务器,并在地址栏中输入下列网址。
http://localhost:8080/c4_ognl_tag/showognl.jsp
其运行界面如图4-4所示。

图4-4 【例4-3】的运行界面