struts2的OGNL表达式的使用



struts2的OGNL表达式的使用。要谈OGNL在Struts2中的应用,首先得明白OGNL到底是什么

在值栈中的对象,可以直接访问,但是用#.对象的时候却又访问不到,但用#this.对象的时候又可以访问得到,用%所有的没关系的

OGNL 的历史

OGNL 最初是为了能够使用对象的属性名来建立 UI 组件 (component) 和 控制器 (controllers) 之间的联系,简单来说就是:视图 与 控制器 之间数据的联系。后来为了应付更加复杂的数据关系,Drew Davidson 发明了一个被他称为 KVCL(Key-Value Coding Language) 的语言。 Luke 参与进来后,用 ANTLR 来实现了该语言,并给它取了这个新名字,他后来又使用 JavaCC 重新实现了该语言。目前 OGNL 由 Drew 来负责维护。目前很多项目中都用到了 OGNL,其中不乏为大家所熟知的,例如几个流行的 web 应用框架:WebWork【当然struts2也可以说是WebWork升级版】,Tapestry 等。

 

什么是 OGNL?

OGNL 是 Object-Graph Navigation Language 的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航,OGNL 在许多的地方都有应用,例如:

1)作为 GUI 元素(textfield,combobox, 等)到模型对象的绑定语言。

2)数据库表到 Swing 的 TableModel 的数据源语言。

3)web 组件和后台 Model 对象的绑定语言 (WebOGNL,Tapestry,WebWork,WebObjects) 。

4)作为 Jakarata Commons BeanUtils 或者 JSTL 的表达式语言的一个更具表达力的替代语言。

 

另外,java 中很多可以做的事情,也可以使用 OGNL 来完成,例如:列表映射和选择。对于开发者来说,使用 OGNL,可以用简洁的语法来完成对 java 对象的导航。通常来说:通过一个“路径”来完成对象信息的导航,这个“路径”可以是到 java bean 的某个属性,或者集合中的某个索引的对象,等等,而不是直接使用 get 或者 set 方法来完成

 

 

 

OGNL 的基本语法

OGNL 表达式一般都很简单。虽然 OGNL 语言本身已经变得更加丰富了也更强大了,但是一般来说那些比较复杂的语言特性并未影响到 OGNL 的简洁:简单的部分还是依然那么简单。比如要获取一个对象的 name 属性,OGNL 表达式就是 name, 要获取一个对象的 headline 属性的 text 属性,OGNL 表达式就是 headline.text 。 OGNL 表达式的基本单位是“导航链”,往往简称为“链”。最简单的链包含如下部分:

表达式组成部分      示例

属性名称           如上述示例中的 name 和 headline.text

方法调用           hashCode() 返回当前对象的哈希码。

数组元素           listeners[0] 返回当前对象的监听器列表中的第一个元素。

 

所有的 OGNL 表达式都基于当前对象的上下文来完成求值运算,链的前面部分的结果将作为后面求值的上下文。你的链可以写得很长,例如:

name.toCharArray()[0].numericValue.toString()

 

上面的表达式的求值步骤:

提取根 (root) 对象的 name 属性。

调用上一步返回的结果字符串的 toCharArray() 方法。

提取返回的结果数组的第一个字符。

获取字符的 numericValue 属性,该字符是一个 Character 对象,Character 类有一个 getNumericValue() 方法。

调用结果 Integer 对象的 toString() 方法。

上面的例子只是用来得到一个对象的值,OGNL 也可以用来去设置对象的值。当把上面的表达式传入 Ognl.setValue() 方法将导致 InappropriateExpressionException,因为链的最后的部分(toString())既不是一个属性的名字也不是数组的某个元素。了解了上面的语法基本上可以完成绝大部分工作了。

 

OGNL 表达式

1)常量:字符串:“ hello ” 字符:‘ h ’ 数字:除了像 java 的内置类型 int,long,float 和 double,Ognl 还有如例:

0.01B,相当于 java.math.BigDecimal,使用’ b ’或者’ B ’后缀。 100000H,相当于 java.math.BigInteger,使用’ h ’ 或 ’ H ’ 后缀。

2)属性的引用例如:user.name

3)变量的引用例如:#name

4)静态变量的访问使用 @class@field

5)静态方法的调用使用 @class@method(args), 如果没有指定 class 那么默认就使用 java.lang.Math.

6)构造函数的调用例如:new java.util.ArrayList();

其它的 Ognl 的表达式可以参考 Ognl 的语言手册。

 

 

OGNL的性能

 

OGNL,或者说表达式语言的性能主要又两方面来决定,一个就是对表达式的解析 (Parser),另一个是表达式的执行,OGNL 采用 javaCC 来完成 parser 的实现,在 OGNL 2.7 中又对 OGNL 的执行部分进行了加强,使用 javasisit 来 JIT(Just-In-Time) 的生成 byte code 来完成表达式的执行。 Ognl 给这个功能的名字是:OGNL Expression Compilation 。基本的使用方法是:

SimpleObject root = new SimpleObject();

OgnlContext context =  (OgnlContext) Ognl.createDefaultContext(null);

Node node =  (Node) Ognl.compileExpression(context, root, “user.name”);

String userName = (String)node.getAccessor().get(context, root);

实践证明:OGNL 非常接近 java 直接调用的时间。

 

 

 

表达式语言主要有以下几大好处:

1)避免(MyType) request.getAttribute()和myBean.getMyProperty()之类的语句,使页面更简洁;

2)支持运算符(如+-*/),比普通的标志具有更高的自由度和更强的功能;

3)简单明了地表达代码逻辑,使用代码更可读与便于维护。

 

Struts 2中的表达式语言

Struts 2支持以下几种表达式语言:

1)OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言;

2)JSTL(JSP Standard Tag Library),JSP 2.0集成的标准的表达式语言;

3)Groovy,基于Java平台的动态语言,它具有时下比较流行的动态语言(如Python、Ruby和Smarttalk等)的一些起特性;

4)Velocity,严格来说不是表达式语言,它是一种基于Java的模板匹配引擎,具说其性能要比JSP好。

 

Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:

支持对象方法调用,如xxx.doSomeSpecial();

支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@java.lang.String@format(‘foo %s’, ‘bar’)或@tutorial.MyConstant@APP_NAME;

支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(),这个表达式会返回80;

访问OGNL上下文(OGNL context)和ActionContext;

操作集合对象。

 

 

 

Struts2中ONGL的使用示例

index.html

 

  1. <span style=”font-size: 18px;”><span style=”font-size: 18px;”><html>
  2.     <head>
  3.          <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
  4.         <meta http-equiv=”refresh” content=”0; url=ognl.action” />
  5.     </head>
  6. </html></span></span>
<html>
	<head>
		 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
		<meta http-equiv="refresh" content="0; url=ognl.action" />
	</head>
</html>

 

User.java


 

  1. <span style=”font-size: 18px;”><span style=”font-size: 18px;”>package com.javacrazyer.web.action;
  2. import java.util.Date;
  3. public class User {
  4.     private Integer id;
  5.     private String loginname;
  6.     private Double score;
  7.     private Boolean gender;
  8.     private Character cha;
  9.     private Date birthday;
  10.     public User(){}
  11.     public User(Integer id, String loginname, Double score, Boolean gender,
  12.             Character cha, Date birthday) {
  13.         this.id = id;
  14.         this.loginname = loginname;
  15.         this.score = score;
  16.         this.gender = gender;
  17.         this.cha = cha;
  18.         this.birthday = birthday;
  19.     }
  20.     public Integer getId() {
  21.         return id;
  22.     }
  23.     public void setId(Integer id) {
  24.         this.id = id;
  25.     }
  26.     public String getLoginname() {
  27.         return loginname;
  28.     }
  29.     public void setLoginname(String loginname) {
  30.         this.loginname = loginname;
  31.     }
  32.     public Double getScore() {
  33.         return score;
  34.     }
  35.     public void setScore(Double score) {
  36.         this.score = score;
  37.     }
  38.     public Boolean getGender() {
  39.         return gender;
  40.     }
  41.     public void setGender(Boolean gender) {
  42.         this.gender = gender;
  43.     }
  44.     public Character getCha() {
  45.         return cha;
  46.     }
  47.     public void setCha(Character cha) {
  48.         this.cha = cha;
  49.     }
  50.     public Date getBirthday() {
  51.         return birthday;
  52.     }
  53.     public void setBirthday(Date birthday) {
  54.         this.birthday = birthday;
  55.     }
  56.     public String info() {
  57.         return “User [birthday=" + birthday + ", cha=" + cha + ", gender="
  58.                 + gender + ", id=" + id + ", loginname=" + loginname
  59.                 + ", score=" + score + "]“;
  60.     }
  61. }</span></span>
package com.javacrazyer.web.action;

import java.util.Date;

public class User {
	private Integer id;
	private String loginname;
	private Double score;
	private Boolean gender;
	private Character cha;
	private Date birthday;

	public User(){}

	public User(Integer id, String loginname, Double score, Boolean gender,
			Character cha, Date birthday) {
		this.id = id;
		this.loginname = loginname;
		this.score = score;
		this.gender = gender;
		this.cha = cha;
		this.birthday = birthday;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLoginname() {
		return loginname;
	}
	public void setLoginname(String loginname) {
		this.loginname = loginname;
	}
	public Double getScore() {
		return score;
	}
	public void setScore(Double score) {
		this.score = score;
	}
	public Boolean getGender() {
		return gender;
	}
	public void setGender(Boolean gender) {
		this.gender = gender;
	}
	public Character getCha() {
		return cha;
	}
	public void setCha(Character cha) {
		this.cha = cha;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String info() {
		return "User [birthday=" + birthday + ", cha=" + cha + ", gender="
				+ gender + ", id=" + id + ", loginname=" + loginname
				+ ", score=" + score + "]";
	}
}

 

OGNLAction.java

 

  1. <span style=”font-size: 18px;”><span style=”font-size: 18px;”>package com.javacrazyer.web.action;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. import java.util.HashMap;
  5. import java.util.LinkedHashSet;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Set;
  9. import org.apache.struts2.ServletActionContext;
  10. import com.opensymphony.xwork2.ActionContext;
  11. import com.opensymphony.xwork2.ActionSupport;
  12. public class OGNLAction extends ActionSupport {
  13.     private static final long serialVersionUID = -2554018432709689579L;
  14.     private String loginname;
  15.     private String pwd;
  16.     private User user;
  17.     private Set<String> courseSet;
  18.     private List<String> list;
  19.     private Map<String,String> map;
  20.     private List<User> userList;
  21.     public String <span style=”color: rgb(0, 0, 102);”><strong>execute()</strong></span> throws Exception{
  22.         this.loginname = “xkkkkkkkkkkkkkkkkkkkkkkkk”;
  23.         this.user = new User(123, “wrr”, 88.9, true, ‘B’, new Date());
  24.         this.courseSet = new LinkedHashSet<String>();
  25.         this.courseSet.add(“corejava”);
  26.         this.courseSet.add(“JSP/Servlet”);
  27.         this.courseSet.add(“S2SH”);
  28.         this.list = new ArrayList<String>(this.courseSet);
  29.         this.map = new HashMap<String, String>();
  30.         this.map.put(“x”, “xxx”);
  31.         this.map.put(“y”, “yyy”);
  32.         this.map.put(“z”, “zzz”);
  33.         <span style=”color: rgb(153, 51, 153);”>ActionContext context = ActionContext.getContext();
  34.         context.put(“uname”, “cheney”);
  35.         context.put(“inte”, Integer.valueOf(888888));
  36.         context.put(“user2″, new User(123, “xxk”, 88.9, true, ‘B’, new Date()));</span>
  37.         this.userList = new ArrayList<User>();
  38.         this.userList.add(new User(1, “zs”, 48.9, true, ‘D’, new Date()));
  39.         this.userList.add(new User(2, “ls”, 68.1, true, ‘C’, new Date()));
  40.         this.userList.add(new User(3, “ww”, 78.2, false, ‘B’, new Date()));
  41.         this.userList.add(new User(4, “zl”, 88.3, true, ‘A’, new Date()));
  42.         //—————————————————————–
  43.         //推荐方式:不会跟Servlet API耦合
  44.         context.put(“reqAtt”, “往ActionContext中put的属性”);
  45.         context.getSession().put(“sesAtt”, “往ActionContext.getSession()中put的属性”);
  46.         context.getApplication().put(“appAtt”, “往ActionContext.getApplication()中put的属性”);
  47.         ServletActionContext.getRequest().setAttribute(“reqAtt2″, “Request作用域中的属性”);
  48.         ServletActionContext.getRequest().getSession().setAttribute(“sesAtt2″, “Session作用域中的属性”);
  49.         ServletActionContext.getServletContext().setAttribute(“appAtt2″, “Application作用域中的属性”);
  50.         return SUCCESS;
  51.     }
  52.     public String getAppName(){
  53.         return “这是OGNL的使用示例代码”;
  54.     }
  55.     public String getLoginname() {
  56.         return loginname;
  57.     }
  58.     public void setLoginname(String loginname) {
  59.         this.loginname = loginname;
  60.     }
  61.     public String getPwd() {
  62.         return pwd;
  63.     }
  64.     public void setPwd(String pwd) {
  65.         this.pwd = pwd;
  66.     }
  67.     public User getUser() {
  68.         return user;
  69.     }
  70.     public void setUser(User user) {
  71.         this.user = user;
  72.     }
  73.     public Set<String> getCourseSet() {
  74.         return courseSet;
  75.     }
  76.     public void setCourseSet(Set<String> courseSet) {
  77.         this.courseSet = courseSet;
  78.     }
  79.     public List<String> getList() {
  80.         return list;
  81.     }
  82.     public void setList(List<String> list) {
  83.         this.list = list;
  84.     }
  85.     public Map<String, String> getMap() {
  86.         return map;
  87.     }
  88.     public void setMap(Map<String, String> map) {
  89.         this.map = map;
  90.     }
  91.     public List<User> getUserList() {
  92.         return userList;
  93.     }
  94.     public void setUserList(List<User> userList) {
  95.         this.userList = userList;
  96.     }
  97. }</span></span>
package com.javacrazyer.web.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class OGNLAction extends ActionSupport {
	private static final long serialVersionUID = -2554018432709689579L;
	private String loginname;
	private String pwd;
	private User user;
	private Set<String> courseSet;
	private List<String> list;
	private Map<String,String> map;
	private List<User> userList;

	public String execute() throws Exception{
		this.loginname = "xkkkkkkkkkkkkkkkkkkkkkkkk";
		this.user = new User(123, "wrr", 88.9, true, 'B', new Date());
		this.courseSet = new LinkedHashSet<String>();
		this.courseSet.add("corejava");
		this.courseSet.add("JSP/Servlet");
		this.courseSet.add("S2SH");

		this.list = new ArrayList<String>(this.courseSet);
		this.map = new HashMap<String, String>();
		this.map.put("x", "xxx");
		this.map.put("y", "yyy");
		this.map.put("z", "zzz");

		ActionContext context = ActionContext.getContext();
		context.put("uname", "cheney");
		context.put("inte", Integer.valueOf(888888));
		context.put("user2", new User(123, "xxk", 88.9, true, 'B', new Date()));

		this.userList = new ArrayList<User>();
		this.userList.add(new User(1, "zs", 48.9, true, 'D', new Date()));
		this.userList.add(new User(2, "ls", 68.1, true, 'C', new Date()));
		this.userList.add(new User(3, "ww", 78.2, false, 'B', new Date()));
		this.userList.add(new User(4, "zl", 88.3, true, 'A', new Date()));

		//-----------------------------------------------------------------
		//推荐方式:不会跟Servlet API耦合
		context.put("reqAtt", "往ActionContext中put的属性");
		context.getSession().put("sesAtt", "往ActionContext.getSession()中put的属性");
		context.getApplication().put("appAtt", "往ActionContext.getApplication()中put的属性");

		ServletActionContext.getRequest().setAttribute("reqAtt2", "Request作用域中的属性");
		ServletActionContext.getRequest().getSession().setAttribute("sesAtt2", "Session作用域中的属性");
		ServletActionContext.getServletContext().setAttribute("appAtt2", "Application作用域中的属性");

		return SUCCESS;
	}

	public String getAppName(){
		return "这是OGNL的使用示例代码";
	}

	public String getLoginname() {
		return loginname;
	}
	public void setLoginname(String loginname) {
		this.loginname = loginname;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Set<String> getCourseSet() {
		return courseSet;
	}

	public void setCourseSet(Set<String> courseSet) {
		this.courseSet = courseSet;
	}

	public List<String> getList() {
		return list;
	}

	public void setList(List<String> list) {
		this.list = list;
	}

	public Map<String, String> getMap() {
		return map;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}

	public List<User> getUserList() {
		return userList;
	}

	public void setUserList(List<User> userList) {
		this.userList = userList;
	}

}

 

src/struts.xml

 

  1. <span style=”font-size: 18px;”><span style=”font-size: 18px;”><?xml version=”1.0″ encoding=”UTF-8″ ?>
  2. <!DOCTYPE struts PUBLIC
  3.     “-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN”
  4.     “http://struts.apache.org/dtds/struts-2.1.7.dtd”>
  5. <struts>
  6.     <!– 请求参数的编码方式 –>
  7.     <constant name=”struts.i18n.encoding” value=”UTF-8″/>
  8.     <!– 指定被struts2处理的请求后缀类型。多个用逗号隔开 –>
  9.     <constant name=”struts.action.extension” value=”action,do,go,xkk”/>
  10.     <!– 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  –>
  11.     <constant name=”struts.configuration.xml.reload” value=”true”/>
  12.     <!– 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  –>
  13.     <constant name=”struts.devMode” value=”false”/>
  14.     <!– 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  –>
  15.     <constant name=”struts.serve.static.browserCache” value=”false” />
  16.     <!– 是否允许在OGNL表达式中调用静态方法,默认值为false –>
  17.     <constant name=”struts.ognl.allowStaticMethodAccess” value=”true”/>
  18.     <!– 指定由spring负责action对象的创建
  19.     <constant name=”struts.objectFactory” value=”spring” />
  20.     –>
  21.     <!– 是否开启动态方法调用 –>
  22.     <constant name=”struts.enable.DynamicMethodInvocation” value=”false”/>
  23.     <package name=”my” extends=”struts-default” namespace=”/”>
  24.         <action name=”ognl” class=”com.javacrazyer.web.action.OGNLAction”>
  25.             <result>/ognl_info.jsp</result>
  26.         </action>
  27.     </package>
  28. </struts></span></span>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">

<struts>
	<!-- 请求参数的编码方式 -->
	<constant name="struts.i18n.encoding" value="UTF-8"/>
	<!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
	<constant name="struts.action.extension" value="action,do,go,xkk"/>
	<!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  -->
	<constant name="struts.configuration.xml.reload" value="true"/>
	<!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  -->
	<constant name="struts.devMode" value="false"/>
	<!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  -->
	<constant name="struts.serve.static.browserCache" value="false" />
	<!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
	<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>

	<!-- 指定由spring负责action对象的创建 
	<constant name="struts.objectFactory" value="spring" />
	-->
	<!-- 是否开启动态方法调用 -->
	<constant name="struts.enable.DynamicMethodInvocation" value="false"/>

	<package name="my" extends="struts-default" namespace="/">
		<action name="ognl">
			<result>/ognl_info.jsp</result>
		</action>
	</package>

</struts>

 

  1. <span style=”font-size: 18px;”><span style=”font-size: 18px;”><%@ page language=”java” import=”java.util.*” pageEncoding=”utf-8″%>
  2. <%@ taglib uri=”/struts-tags” prefix=”s” %>
  3. <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
  4. <html>
  5.   <head>
  6.     <title>OGNL的使用</title>
  7.   </head>
  8.   <body>
  9. <h3>OGNL的使用</h3><hr/>
  10. <span style=”color: rgb(102, 0, 204);”>访问Action中的普通属性</span>: <s:property value=”loginname”/><br/>
  11. <span style=”color: rgb(255, 102, 0);”>访问Action中的对象属性</span>: <s:property value=”user.birthday”/><br/>
  12. 访问Action中的Set属性: <s:property value=”courseSet.toArray()[0]“/><br/>
  13. 访问Action中的List属性: <s:property value=”list[0]“/><br/>
  14. 访问Action中的Map属性的键: <s:property value=”map.keys.toArray()[1]“/><br/>
  15. 访问Action中的Map属性的值: <s:property value=”map.values.toArray()[1]“/><br/>
  16. 访问Action中的Map属性的指定键对应的值: <s:property value=”map['z']“/><br/>
  17. 访问Action中的Map属性的大小: <s:property value=”map.size”/><br/>
  18. <hr/>
  19. 访问ActionContext中的普通属性:<s:property value=”#inte”/><br/>
  20. 访问ActionContext中的对象属性:<s:property value=”#user2.loginname”/><br/>
  21. <hr/>
  22. <strong><span style=”color: rgb(102, 0, 204);”>访问Action中的普通方法:<s:property value=”getAppName()”/><br/></span></strong>
  23. 访问ActionContext中的某个对象上的普通方法:<s:property value=”#user2.info()”/><br/>
  24. <hr/>
  25. <span style=”color: rgb(51, 204, 0);”>访问静态属性:<s:property value=”@java.lang.Math@PI”/><br/>
  26. 访问静态方法:<s:property value=”@java.lang.Math@floor(44.56)”/><br/></span>
  27. 访问Math类中的静态方法:<s:property value=”@@floor(44.56)”/><br/>
  28. <hr/>
  29. <span style=”color: rgb(204, 0, 0);”>调用java.util.Date的构造方法</span>:<s:date name=”new java.util.Date()” format=”yyyy-MM-dd HH:mm:ss”/><br/>
  30. 调用java.util.Date的构造方法创建对象,再调用它的方法:<s:property value=”new java.util.Date().getTime()”/><br/>
  31. <hr/>
  32. 投影查询:获取userList中所有loginname的列表:<s:property value=”userList.{loginname}”/><br/>
  33. 选择查询:获取userList中所有score大于60的loginname列表:<s:property value=”userList.{?#this.score>60.0}.{loginname}”/><br/>
  34. 选择查询:获取userList中所有score大于60并且gender为true的loginname列表:<s:property value=”userList.{?(#this.score>60.0 && #this.gender)}.{loginname}”/><br/>
  35. 选择查询:获取userList中所有score大于60并且gender为true的第一个元素的loginname:<s:property value=”userList.{^(#this.score>60.0 && #this.gender)}.{loginname}”/><br/>
  36. 选择查询:获取userList中所有score大于60并且gender为true的最后一个元素的loginname:<s:property value=”userList.{$(#this.score>60.0 && #this.gender)}.{loginname}”/><br/>
  37. <hr/>
  38. 访问名为xxx的请求参数对应的第一个值:<s:property value=”#parameters.xxx[0]“/><br/>
  39. 访问通过ActionContext中放入Request中的属性:<s:property value=”#request.reqAtt”/><br/>
  40. 访问通过ServletActionContext中放入Request中的属性:<s:property value=”#request.reqAtt2″/><br/>
  41. 访问通过ActionContext中放入Session中的属性:<s:property value=”#session.sesAtt”/><br/>
  42. 访问通过ServletActionContext中放入Session中的属性:<s:property value=”#session.sesAtt2″/><br/>
  43. 访问通过ActionContext中放入ServletContext中的属性:<s:property value=”#application.appAtt”/><br/>
  44. 访问通过ServletActionContext中放入ServletContext中的属性:<s:property value=”#application.appAtt2″/><br/>
  45. 直接访问属性域中指定名称的属性对应的值:<s:property value=”#attr.sesAtt2″/><br/>
  46. <br/><br/><hr/>
  47. <s:iterator value=”userList” status=”vs”>
  48.     <s:if test=”%{#vs.odd}”>
  49.         <span style=”color: red”>
  50.             <s:property value=”#vs.count”/>: <s:property value=”loginname”/>,<s:date name=”birthday” format=”yyyy-MM-dd HH:mm:ss”/><br/>
  51.         </span>
  52.     </s:if>
  53.     <s:else>
  54.         <span style=”color: blue”>
  55.             <s:property value=”#vs.count”/>: <s:property value=”loginname”/>,<s:date name=”birthday” format=”yyyy-MM-dd HH:mm:ss”/><br/>
  56.         </span>
  57.     </s:else>
  58. </s:iterator>
  59. <hr/><s:debug/>
  60.   </body>
  61. </html></span></span>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>OGNL的使用</title>
  </head>
  <body>
<h3>OGNL的使用</h3><hr/>
 访问Action中的普通属性: <s:property value="loginname"/><br/>
 访问Action中的对象属性: <s:property value="user.birthday"/><br/>
 访问Action中的Set属性: <s:property value="courseSet.toArray()[0]"/><br/>
 访问Action中的List属性: <s:property value="list[0]"/><br/>
 访问Action中的Map属性的键: <s:property value="map.keys.toArray()[1]"/><br/>
 访问Action中的Map属性的值: <s:property value="map.values.toArray()[1]"/><br/>
访问Action中的Map属性的指定键对应的值: <s:property value="map['z']"/><br/> 
访问Action中的Map属性的大小: <s:property value="map.size"/><br/> 
<hr/>
访问ActionContext中的普通属性:<s:property value="#inte"/><br/>
访问ActionContext中的对象属性:<s:property value="#user2.loginname"/><br/>
<hr/>
访问Action中的普通方法:<s:property value="getAppName()"/><br/>
访问ActionContext中的某个对象上的普通方法:<s:property value="#user2.info()"/><br/>
<hr/>
访问静态属性:<s:property value="@java.lang.Math@PI"/><br/>
访问静态方法:<s:property value="@java.lang.Math@floor(44.56)"/><br/>
访问Math类中的静态方法:<s:property value="@@floor(44.56)"/><br/>
<hr/>
调用java.util.Date的构造方法:<s:date name="new java.util.Date()" format="yyyy-MM-dd HH:mm:ss"/><br/>
调用java.util.Date的构造方法创建对象,再调用它的方法:<s:property value="new java.util.Date().getTime()"/><br/>
<hr/>
投影查询:获取userList中所有loginname的列表:<s:property value="userList.{loginname}"/><br/>
选择查询:获取userList中所有score大于60的loginname列表:<s:property value="userList.{?#this.score>60.0}.{loginname}"/><br/>
选择查询:获取userList中所有score大于60并且gender为true的loginname列表:<s:property value="userList.{?(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>
选择查询:获取userList中所有score大于60并且gender为true的第一个元素的loginname:<s:property value="userList.{^(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>
选择查询:获取userList中所有score大于60并且gender为true的最后一个元素的loginname:<s:property value="userList.{$(#this.score>60.0 && #this.gender)}.{loginname}"/><br/>
<hr/>
访问名为xxx的请求参数对应的第一个值:<s:property value="#parameters.xxx[0]"/><br/>
访问通过ActionContext中放入Request中的属性:<s:property value="#request.reqAtt"/><br/>
访问通过ServletActionContext中放入Request中的属性:<s:property value="#request.reqAtt2"/><br/>

访问通过ActionContext中放入Session中的属性:<s:property value="#session.sesAtt"/><br/>
访问通过ServletActionContext中放入Session中的属性:<s:property value="#session.sesAtt2"/><br/>
访问通过ActionContext中放入ServletContext中的属性:<s:property value="#application.appAtt"/><br/>
访问通过ServletActionContext中放入ServletContext中的属性:<s:property value="#application.appAtt2"/><br/>

直接访问属性域中指定名称的属性对应的值:<s:property value="#attr.sesAtt2"/><br/>
<br/><br/><hr/>
<s:iterator value="userList" status="vs">
	<s:if test="%{#vs.odd}">
		<span style="color: red">
			<s:property value="#vs.count"/>: <s:property value="loginname"/>,<s:date name="birthday" format="yyyy-MM-dd HH:mm:ss"/><br/>
		</span>
	</s:if>
	<s:else>
		<span style="color: blue">
			<s:property value="#vs.count"/>: <s:property value="loginname"/>,<s:date name="birthday" format="yyyy-MM-dd HH:mm:ss"/><br/>
		</span>
	</s:else>
</s:iterator>

<hr/><s:debug/>
  </body>
</html>

 

总结:

在上边大家都好奇为什么都用struts的S标签,因为OGNL是通常要结合Struts 2的标志一起使用,如<s:property value=”xx” />

 

Action类与JSP页面之间的数据传递

1) 通过HttpServletRequest,HttpSession,ServletContext来传递数据。

a) Action中传数据:在Action类的请求处理方法中先获取各个作用域对象

ServletActionContext.getRequest();

ServletActionContext.getRequest().getSession();

ServletActionContext.getServletContext();

然后调用相应的setAttribute(String “键”, Object 值);

b) 在JSP页面中取数据:可以使用EL表达式或代码片段来取出对应作用域中属性值。

c) 页面中的请求参数传递到Action中时,Action中直接定义对应名称的属性,并提供setter方法即可封装此数据。

2) 通过ActionContext实例来传递数据。 ActionContext针对每个正在执行Action的线程中绑定一份。

a) Action中通过ActionContext传递数据。

ActionContext提供了put(String “键”, Object 值);  //数据不会映射到HttpServletRequest中。

ActionContext提供的getSession().put(String “键”, Object 值);  //数据会自动映射到HttpSession中。

ActionContext提供的getApplication().put(String “键”, Object 值); //数据会自动映射到ServletContext中。

b) 在JSP页面取数据:struts2推荐使用OGNL来取ActionContext中的数据。

 

 

1. Struts2中的OGNL的使用。

 

2. OGNL:对象图导航语言。通过OGNL表达式可以获取对象的属性,调用对象的方法,或构造出对象。

1) OGNL上下文中有一个根对象。这个根对象可以直接获取。不需要#。

2)支持常量:

字符串常量、字符常量、

数值常量:int、long、float、double

布尔常量:true、false

Null常量 : null

支持操作符:支持Java的所有操作符,还支持特有的操作符: ,、 {}、in、not in;

 

Struts2中的OGNL:

1) Struts2将ActionContext设置为OGNL上下文,并将值栈(ValueStack)作为OGNL的根对象放置到ActionContext中。

2) Struts2总是把当前Action实例放置在值栈的栈顶。所以,在OGNL中引用Action中的属性也可以省略“#”。

 

常用标签

1) <s:property value=”OGNL”/>

2) <s:date name=”OGNL” format=”"/>

3) <s:if test=”OGNL”></s:if><s:elseif test=”OGNL”></s:elseif><s:else></s:else>

★4) <s:iterator value=”OGNL” status=”vs”>…</s:iterator>

5) <s:debug/>

 

 

struts2中#、%和$这三个符号的使用方法【摘自max struts2教程】

 

一、”#”的用法

1、 访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:

parameters 包含当前HTTP请求参数的Map #parameters.id[0]作用相当于request.getParameter(“id”)

request 包含当前HttpServletRequest的属性(attribute)的Map #request.userName相当于request.getAttribute(“userName”)

session 包含当前HttpSession的属性(attribute)的Map #session.userName相当于session.getAttribute(“userName”)

application 包含当前应用的ServletContext的属性(attribute)的Map #application.userName相当于application.getAttribute(“userName”)

attr 用于按request > session > application顺序访问其属性(attribute) #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止

2、用于过滤和投影(projecting)集合,如books.{?#this.price<100};

3、构造Map,如#{‘foo1′:’bar1′, ‘foo2′:’bar2′}。

 

二、”%”的用法

“%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。例如在Ognl.jsp中加入以下代码:

<h3>%的用途</h3>

<p><s:url value=”#foobar['foo1']” /></p>

<p><s:url value=”%{#foobar['foo1']}” /></p>

 

三、”$”的用法

1、用于在国际化资源文件中,引用OGNL表达式

2、在Struts 2配置文件中,引用OGNL表达式

例如:

<action name=”AddPhoto”>

<interceptor-ref name=”fileUploadStack” />

<result type=”redirect”>ListPhotos.action?       albumId=${albumId}</result>

</action>