在实际开发过程中,OGNL 表达式要结合 struts2 的标签使用,主要就是%、#和$三个符号的使用。由于$被广泛应用于 EL 中,所以本小节将重点介绍%和#的用法。
在 Struts2 框架中,#符号有三种用途,分别如下:
1)访问非根对象的属性。如访问 OGNL 上下文和 Action 上下文。由于 Struts2 中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。
#相当于 ActionContext.getContext()。例如‘#session.user’表达式相当于 ActionContext.getContext().getSession().getAttribute("user"),‘#request.userName’表达式相当于 request.getAttribute("userName")。
2)用于过滤和投影集合。如 books.{?#this.price>25}。
3)构造 Map。如 #{key1:value1,key2:value2},这种方式常用于给 radio 或 select、checkbox 等标签赋值。如果要在页面中取一个 Map 的值可以如下书写:<s:property value="#myMap['key']"/>。
%是在标签的属性值被理解为字符串类型时,告诉执行环境‘%{}’中的是 OGNL 表达式,并计算 OGNL 表达式的值。
$符号主要用于在 Struts2 配置文件中引入 OGNL 表达式。例如下面的配置所示:
- <action name="userAction_*" class="userAction" method="{1}">
- <result name="add" type="redirect">
- userAction_findById?userId=${User.userId}
- </result>
- </action>
为了让读者更好地理解和掌握 OGNL,下面通过一个案例演示 OGNL 的使用。
在 MyEclipse 中创建一个名称为 struts2Demo05 的 Web 项目,并引入 Struts2 所需 JAR 包,然后添加上过滤器信息。
在项目的 src 目录下创建一个名称为 com.mengma.ognl 的包,在包中新建一个名称为 Person 的类,该类中包含 name、age 和 birthday 三个属性以及其 getter 和 setter 方法,如下所示。
- package com.mengma.ognl;
- import java.util.Date;
- public class Person {
- private String name;
- private int age;
- private Date birthday;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public Date getBirthday() {
- return birthday;
- }
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
- }
在 com.mengma.ognl 包中创建一个名称为 OgnlAction 的 Action 类,编辑后如下所示。
- package com.mengma.ognl;
- import java.util.Date;
- import java.util.LinkedList;
- import java.util.List;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.struts2.ServletActionContext;
- import com.opensymphony.xwork2.ActionContext;
- import com.opensymphony.xwork2.ActionSupport;
- public class OgnlAction extends ActionSupport {
- private List<Person> persons; // 声明Person对象
- public List<Person> getPersons() {
- return persons;
- }
- public void setPersons(List<Person> persons) {
- this.persons = persons;
- }
- // 测试方法
- public String ognlTest() throws Exception {
- // 获得ActionContext实例
- ActionContext ctx = ActionContext.getContext();
- ctx.getApplication().put("msg", "application信息"); // 存入application中
- ctx.getSession().put("msg", "session信息"); // 保存session
- HttpServletRequest request = ServletActionContext.getRequest();
- // 保存到request
- request.setAttribute("msg", "request信息");
- persons = new LinkedList<Person>();
- Person person1 = new Person();
- person1.setName("AAA");
- person1.setAge(26);
- person1.setBirthday(new Date());
- persons.add(person1);
- Person person2 = new Person();
- person2.setName("BBB");
- person2.setAge(36);
- person2.setBirthday(new Date());
- persons.add(person2);
- Person person3 = new Person();
- person3.setName("CCC");
- person3.setAge(16);
- person3.setBirthday(new Date());
- persons.add(person3);
- return SUCCESS;
- }
- }
上述代码中,首先声明了 Person 对象,并实现了它的 getter 和 setter 方法。然后在测试方法 ognlTest() 中,首先获得了 ActionContext 实例,然后通过 ActionContext 的实例分别向 Application、Session 和 Request 中存入相应信息,最后创建了 Person 对象,并向 Person 对象中添加了三个人员信息。
在项目的 src 目录下创建配置文件 struts.xml,并配置 Action 的信息。编辑后如下所示。
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
- "http://struts.apache.org/dtds/struts-2.3.dtd">
- <struts>
- <package name="struts2" namespace="/" extends="struts-default">
- <action name="ognl" class="com.mengma.ognl.OgnlAction" method="ognlTest">
- <result>/ognl.jsp</result>
- </action>
- </package>
- </struts>
在项目的 WebContent 目录下创建一个名称为 ognl.jsp 的文件,编辑代码后如下所示。
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <%@taglib prefix="s" uri="/struts-tags"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>OGNL的使用</title>
- </head>
- <body>
- <h3>访问OGNL上下文和Action上下文</h3>
- <!-- 使用OGNL访问属性值 -->
- <p>
- request.msg:
- <s:property value="#request.msg" />
- </p>
- <p>
- session.msg:
- <s:property value="#session.msg" />
- </p>
- <p>
- application.msg:
- <s:property value="#application.msg" />
- </p>
- <p>
- attr.msg:
- <s:property value="#attr.msg" />
- </p>
- <hr />
- <h3>用于过滤和投影集合</h3>
- <p>年龄大于20</p>
- <ul>
- <!-- 判断年龄 -->
- <s:iterator value="persons.{?#this.age>20}">
- <li><s:property value="name" />-年龄:<s:property value="age" />
- </li>
- </s:iterator>
- </ul>
- <p>
- 姓名为AAA的年龄:
- <s:property value="persons.{?#this.name=='AAA'}.{age}{0}" />
- </p>
- <hr />
- <h3>构造Map</h3>
- <s:set name="foobar" value="#{'foo1':'bar1','foo2':'bar2'}" />
- <p>
- The value of key "foo1" is
- <s:property value="#foobar[foo1]" />
- </p>
- <hr />
- <h3>%符号的用法</h3>
- <s:set name="key" value="#{'key1':'value1','key2':'value2'}" />
- <p>
- key1的值是
- <s:property value="#key['key1']" />
- </p>
- <p>
- 不使用%:
- <s:url value="#key['key1']" />
- </p>
- <p>
- 使用%:
- <s:url value="%{#key['key1']}" />
- </p>
- <hr />
- <%
- request.setAttribute("req", "request scope");
- request.getSession().setAttribute("sess", "session scope");
- request.getSession().getServletContext()
- .setAttribute("app", "application scope");
- %>
- <h3>通过OGNL表达式获取属性范围中的值</h3>
- <br />
- <s:property value="#request.req" />
- <br />
- <s:property value="#session.sess" />
- <br />
- <s:property value="#application.app" />
- <br />
- </body>
- </html>
启动服务器后,在浏览器的地址栏中输入地址 http://localhost:8080/struts2Demo05/ognl,浏览器的显示结果如图 1 所示。
图 1 OGNL的使用
从图 1 中可以看出,使用 OGNL 表达式已经成功获取了所需要的信息。OGNL 表达式简单、易懂、功能强大,读者可以访问其官方网站获取更多相关资料。