1.什么是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 方法来完成。
2.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() 方法。
3.OGNL表达式
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();
4.表达式语言的好处
表达式语言主要有以下几大好处:
1)避免(MyType) request.getAttribute()和myBean.getMyProperty()之类的语句,使页面更简洁;
2)支持运算符(如+-*/),比普通的标志具有更高的自由度和更强的功能;
3)简单明了地表达代码逻辑,使用代码更可读与便于维护。
5.Stuts2支持的表达式语言
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;
操作集合对象。
6.OGNL的相关知识
2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:property value="xxx"/>。
7.OGNL三个符号 % $ #的使用
OGNL中重要的3个符号:#、%、$:
#符号的用途一般有三种。
— 访问非根对象属性,例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute("msg") 。
— 用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。
— 用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。
2.%符号
3.$符号
$符号主要有两个方面的用途。
— 在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。
— 在Struts 2框架的配置文件中引用OGNL表达式
举例说明:
package com.demo.action;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport {
private List<User> users;
private HttpServletRequest request;
private Map session;
private Map application;
public void setRequest(HttpServletRequest request) {
this.request = request;
}
public void setSession(Map<String, String> session) {
this.session = session;
}
public void setApplication(Map<String, String> application) {
this.application = application;
}
public void setList(List<User> users) {
this.users = users;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public String execute() {
ActionContext act = ActionContext.getContext();
request = ServletActionContext.getRequest(); // 获得request对象
session = act.getSession(); // 获得session对象
application = act.getApplication(); // 获得application对象
request.setAttribute("userName", "from Request");
session.put("userName", "from session");
application.put("userName", "form application");
users = new ArrayList<User>();
users.add(new User("zhangsan", "beijing", 18));
users.add(new User("lisi", "chaoyang", 25));
users.add(new User("wangwu", "beijing", 20));
return SUCCESS;
}
}
User。java
package com.demo.action;
public class User {
private String username;
private String address;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User(String username, String address, int age) {
super();
this.username = username;
this.address = address;
this.age = age;
}
}
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 XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Struts OGNL Demo</title>
</head>
<body>
<h3>访问OGNL上下文和Action上下文</h3>
<p>parameters: <s:property value="#parameters.userName" /></p>
<p>request.userName: <s:property value="#request.userName" /></p>
<p>session.userName: <s:property value="#session.userName" /></p>
<p>application.userName: <s:property value="#application.userName" /></p>
<p>attr.userName: <s:property value="#attr.userName" /></p>
<hr />
<h3>用于过滤和投影(projecting)集合</h3>
<p>age more than 18</p>
<ul>
<s:iterator value="users.{?#this.age > 18}">
<li> username:<s:property value="username" />---<s:property value="address" /></li>
</s:iterator>
</ul>
<p>The address of "beijing" is: <s:property value="users.{?#this.address=='beijing'}.{username}[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>
<p><s:url value="#foobar['foo1']" /></p>
<p><s:url value="%{#foobar['foo1']}" /></p>
</body>
</html>
struts.xml
<?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>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<package name="default" namespace="" extends="struts-default">
<action name="test" class="com.demo.action.TestAction">
<result type="dispatcher">/ognl.jsp</result>
<result name="input">/index.jsp</result>
</action>
<action name="user_*" class="com.demo.action.UserAction" method="{1}">
<result name="login">/login.jsp</result>
<result name="register">/success.jsp</result>
</action>
</package>
</struts>