Ognl表达式语言
l OGNL表达式
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。
l OGNL优势
1、支持对象方法调用,如xxx.doSomeSpecial();
2、支持类静态的方法调用和值访问,表达式的格式:
@[类全名(包括包路径)]@[方法名 | 值名],例如:
@java.lang.String@format('foo %s', 'bar')
或@tutorial.MyConstant@APP_NAME;
3、支持赋值操作和表达式串联,如price=100, discount=0.8,
calculatePrice(),这个表达式会返回80;
4、访问OGNL上下文(OGNL context)和ActionContext;
5、操作集合对象。
OGNL 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map 的接口。
OgnlContext类【本质是一个Map】
分析:Struts框架默认就支持Ognl表达式语言。(struts必须引用的包:ognl.jar)
OgnlContext是Struts2的数据中心。
当Struts2接受一个请求时,会迅速创建ActionContext、ValueStack和Action对象。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。 示意图如下

可以打开OglnContext的源代码,如下:
public class OgnlContext extends Object implements Map
{
public static final String CONTEXT_CONTEXT_KEY = "context";
public static final String ROOT_CONTEXT_KEY = "root";
public static final String THIS_CONTEXT_KEY = "this";
.......
}
有一个特点是继承自Map接口
现在可以写一写其测试类:
package com.gqx.ognl;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
import org.junit.Test;
public class OgnlTest {
/**
* 使用Ognl表达式取值,取非根元素的值,必须要用"#"
*/
@Test
public void test() {
//创建一个OgnlContext上下文对象
OgnlContext context=new OgnlContext();
//存放数据,继承自map接口,所以map形式存放
context.put("name", "gqxing");
//获取数据
String value=(String) context.get("name");
System.out.println(value);
}
@Test
public void test2() throws OgnlException {
//创建一个OgnlContext上下文对象
OgnlContext context=new OgnlContext();
//存放数据,继承自map接口,所以map形式存放
User user=new User();
user.setId(101);
user.setName("gqxing");
context.put("user", user);
//获取数据
/*
* 第一种方式:
User value=(User) context.get("user");
System.out.println(user.getName()+":"+user.getId());
*
*第二种方式
*先构建一个ognl表达式,在解析表达式
*/
//向非根元素取值是,要用"#"号
Object ognl=Ognl.parseExpression("#user.id");
Object value=Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
/**
* Ognl表达式语言语言取值,取根元素的值,不用带#号
* @throws OgnlException
*/
@Test
public void test3() throws OgnlException {
//创建一个OgnlContext上下文对象
OgnlContext context=new OgnlContext();
//存放数据,继承自map接口,所以map形式存放
User user=new User();
user.setId(101);
user.setName("gqxing");
context.put("user", user);
//设置根元素,向根元素放数据
context.setRoot(user);
//获取数据(map)
//向根元素取值是,直接写属性
Object ognl=Ognl.parseExpression("id");
Object value=Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
/**
* 获取属性之下的属性
* @throws OgnlException
*/
@Test
public void test4() throws OgnlException {
//创建一个OgnlContext上下文对象
OgnlContext context=new OgnlContext();
//存放数据,继承自map接口,所以map形式存放
User user=new User();
user.setId(101);
user.setName("gqxing");
context.put("user", user);
//设置根元素,向根元素放数据
context.setRoot(user);
//获取数据(map)
//向根元素取值是,直接写属性
Object ognl=Ognl.parseExpression("address.province");
Object value=Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
/**
* 静态方法调用
* @throws OgnlException
*/
@Test
public void test5() throws OgnlException {
OgnlContext context =new OgnlContext();
//Ognl表达式语言,调用静态方法
//Object ognl=Ognl.parseExpression("@Math@floor(5.6)");
//由于Math类在开发中用的比较多,所以可以这样写
Object ognl=Ognl.parseExpression("@@floor(5.6)");
Object value=Ognl.getValue(ognl, context,context.getRoot());
System.out.println(value);
}
}
Struts2的值栈ValueStack
ValueStack即值栈对象,是整个数据存储的核心,或叫中转站。实现了该接口的OgnlValueStack类。
ValueStack特点
ValueStack贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象. Struts2框架把 ValueStack 对象保存在名为 “struts.valueStack” 的request请求属性中,传入jsp页面。开发者只需通过ActionContext对象就可以直接去访问struts的其他关键对象,(ActionContext是专门给开发者使用的,便于学习和使用)
可以写一个Action来测试其中的关系
package com.gqx.ognl;
import javax.servlet.ServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
/**
* struts的数据流转
* @author GQXing
*
*/
public class OgnlDemo extends ActionSupport{
@Override
public String execute() throws Exception {
//值栈对象存储数据的原理:
ActionContext actionContext=ActionContext.getContext();
ValueStack valueStack2=actionContext.getValueStack();
System.out.println(valueStack2);
return SUCCESS;
}
public String test(){
//获取值栈对象。方式一:
ServletRequest request=ServletActionContext.getRequest();
ValueStack valueStack=(ValueStack) request.getAttribute("struts.valueStack");
//获取值栈对象。方式二
ActionContext actionContext=ActionContext.getContext();
ValueStack valueStack2=actionContext.getValueStack();
System.out.println(valueStack==valueStack2); //true
return SUCCESS;
}
}
加入断点调试,可以看到相应的变量值

可以先写这个程序来测试
package com.gqx.ognl;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class OgnlDemo2 extends ActionSupport{
private User user=new User(101,"gqxing");
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
ActionContext ac=ActionContext.getContext();
Map<String, Object> map=(Map<String, Object>) ac.get("request");
//映射数据
map.put("request_data", "request_data");
map.put("cn", "China");
//ac.getContextMap().put("request_data", "request_data");
ac.getSession().put("Session_data", "Session_data");
ac.getApplication().put("Application_data", "Application_data");
ValueStack vs=ac.getValueStack();
/*********操作根元素的几种方法*********/
// vs.push(new User(111,"hehe")); //入栈顶
// vs.pop(); //栈顶元素出来
//map结构存储
// vs.set("user1", new User(102,"Code"));
// vs.set("user2", new User(103,"Hello"));
System.out.println(vs);
return super.execute();
}
}
当用户在访问这个action的时候,action参数产生的临时数据都保存在ValueStack中,jsp页面要做出响应的反应,都是从这个ValueStack中取数据的。

ValueStack中相应的数据如下

有上面可以得到值栈对象的案例可以得到

创建一个action以及对应的实体配置
package com.gqx.ognl;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class OgnlDemo2 extends ActionSupport{
private User user=new User(101,"gqxing");
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
ActionContext ac=ActionContext.getContext();
// Map<String, Object> map=(Map<String, Object>) ac.get("request");
//映射数据
// map.put("request_data", "request_data");
// map.put("cn", "China");
ac.getContextMap().put("request_data", "request_data");
ac.getSession().put("Session_data", "Session_data");
ac.getApplication().put("Application_data", "Application_data");
ValueStack vs=ac.getValueStack();
/*********操作根元素的几种方法*********/
// vs.push(new User(111,"hehe")); //入栈顶
// vs.pop(); //栈顶元素出来
//map结构存储
// vs.set("user1", new User(102,"Code"));
// vs.set("user2", new User(103,"Hello"));
System.out.println(vs);
return super.execute();
}
}
在xml中配置:
<action name="ognl2" class="com.gqx.ognl.OgnlDemo2">
<result name="success">/ognl.jsp?name=${user.name}</result>
</action>
jsp页面
<%@ 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>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<!-- 页面:必须要拿到ValueStack -->
<br> 取根元素的值<br>
<s:property value="user.id"/>
<s:property value="user.name"/>
<s:property value="user.address.province"/>
<s:property value="user.address.city"/>
<br> 取非根元素的值<br>
<s:property value="#request.cn"/>
<s:property value="#request.request_data"/>
<s:property value="#session.Session_data"/>
<s:property value="#application.Application_data"/>
<br> 通过attr来取非根元素的值<br>
<!-- 自动查找request/session/application,找到后立即自动返回 -->
<s:property value="#attr.cn"/>
<s:property value="#attr.request_data"/>
<s:property value="#attr.Session_data"/>
<s:property value="#attr.Application_data"/>
<br> 2、取非根元素的值<br>
<!-- 这种方式只有在Request中可以用 -->
<s:property value="#request_data"/>
<br>
<!-- 获取请求的参数 -->
<s:property value="#parameters.name"/>
<!--struts的调试标签 ,可以观测值栈数据-->
<s:debug></s:debug>
</body>
</html>
效果如图:

现在利用struts的list和map迭代学习:
先创建一个Action类
package com.gqx.ognl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class OgnlDemo3 extends ActionSupport{
@Override
public String execute() throws Exception {
List<User> list =new ArrayList<User>();
Map<Integer, User> map=new HashMap<Integer, User>();
//初始化
for (int i = 0; i < 11; i++) {
User user=new User(i,"gqxing"+i);
list.add(user);
map.put(user.getId(), user);
}
//保存在request
ActionContext.getContext().getContextMap().put("list", list);
ActionContext.getContext().getContextMap().put("map", map);
/*不加警号
ActionContext.getContext().getValueStack().push(arg0);
*/
return super.execute();
}
}
以及与其对应的jsp页面:
<%@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>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<style type="text/css">
.odd{
background-color: red;'
}
.even{
background: blue;
}
</style>
</head>
<body>
<br>1、list迭代
<br>
<table border="1">
<tr>
<td>编号</td>
<td>名称</td>
</tr>
<s:iterator var="user" value="#request.list" status="st">
<tr class=<s:property value="#st.even?'even':'odd'"/>>
<td><s:property value="#user.id" /></td>
<td><s:property value="#user.name" /></td>
</tr>
</s:iterator>
</table>
<br>1、map迭代
<br>
<table border="1">
<tr>
<td>编号</td>
<td>名称</td>
</tr>
<s:iterator var="entry" value="#request.map" status="st">
<tr class=<s:property value="#st.even?'even':'odd'"/>>
<td><s:property value="#entry.key" /></td>
<td><s:property value="#entry.value.name" /></td>
</tr>
</s:iterator>
</table>
<!-- Ognl表达式 可以取值,也可以动态创建集合-->
<br>一、构建List集合<br>
<s:iterator var="str" value="{'a','b'}">
<s:property value="#str"/>
<br>
</s:iterator>
<br>一、构建Map集合<br>
<s:iterator var="en" value="#{'cn':'China','name':'gqxing' }">
<s:property value="#en.key"/>
<s:property value="#en.value"/>
<br>
</s:iterator>
</body>
</html>
效果如图:

Ognl表达式语言的更多相关文章
- Struts2的OGNL表达式语言
一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...
- OGNL表达式语言网上转来的
1.概念:OGNL是ObjectGraphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语言. 2.功能: ...
- Struts ognl表达式语言几个符号
# 获取非根元素值 . 动态都建map集合 $ 配置文件取值 % 提供一个ognl表达式运行环境 <%@ page language="java" import=&q ...
- Struts2中使用OGNL表达式语言访问静态方法和静态属性
1.一定要在struts.xml配置文件中配置允许使用OGNL访问静态方法,否则不能使用OGNL访问静态方法 2.<s:property value="@com.gk.StaticTe ...
- Ognl表达式基本原理和使用方法
Ognl表达式基本原理和使用方法 1.Ognl表达式语言 1.1.概述 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个 ...
- Spring表达式语言 之 5.1 概述 5.2 SpEL基础(拾叁)
5.1 概述 5.1.1 概述 Spring表达式语言全称为"Spring Expression Language",缩写为"SpEL",类似于Struts ...
- 20160502-struts2入门--ognl表达式
一.OGNL表达式语言 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语言 ...
- ValueStack背后的OGNL表达式
原文地址:http://blog.csdn.net/li_tengfei/archive/2010/12/25/6098134.aspx 前言: Strut2的Action类通过属性可以获得所有相关的 ...
- 开涛spring3(5.1&5.2) - Spring表达式语言 之 5.1 概述 5.2 SpEL基础
5.1 概述 5.1.1 概述 Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行 ...
随机推荐
- 2014年最火的 21个JavaScript 框架
下面,我们将会介绍 2014 年最火的 21 款JavaScript 框架,专为前端开发者准备的哦:)众所周知, JavaScript 框架是 JavaScript编程语言最棒的特性之一. JavaS ...
- nagios&pnp4nagios--yum 安装
一. 环境: 1. centos 6.4 2. 设置hostname 并且安装好apache 3. 关闭selinux及iptables 二. 安装nagios服务器端: 1. rpm -Uvh ht ...
- Vim的tag系统
tag标识符存储在ctags等程序生成的文件里 :tag和<C-]>命令跳转到光标所在符号(若光标不再符号上则为右边第一个符号)的定义处 还有g+鼠标左键和<C-鼠标左键> & ...
- 微软嵌入式WEC2013产品研讨会(深圳站---2013.10.16)
主要内容如下: 1. Windows Embedded Compact 2013面向的市场 主要面向工业自动化.医疗设备和零售行业这些市场,和物联网关系非常紧密. 2. Windo ...
- linux切换用户
当前使用root账户 [root@localhost chucklu]# cd[root@localhost ~]# pwd/root 切换到普通账户 [root@localhost ~]# su c ...
- [转载]12款免费与开源的NoSQL数据库介绍
Naresh Kumar是位软件工程师与热情的博主,对于编程与新事物拥有极大的兴趣,非常乐于与其他开发者和程序员分享技术上的研究成果.近日,Naresh撰文谈到了12款知名的免费.开源NoSQL数据库 ...
- Java和.NET在开发中的不同盘点
我是用VS2008和VS2010开发.NET程序,通过MyEclipse8.5开发JAVA程序,下面从IDE.语言.插件的不同点来做下简单的说明.但由于经验知识还有限,本篇文章只能从比较表面的以及自己 ...
- shareSDK实现QQ第三方登录
// QQ登录 case R.id.login_share_qq: Platform qq = ShareSDK.getPlatform(QQ.NAME); qq.SSOSetting(false); ...
- ↗☻【编写可维护的JavaScript #BOOK#】第9章 将配置数据从代码中分离出来
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- android LayoutInflater和inflate()方法的用法(转载)
原文出处:http://www.cnblogs.com/top5/archive/2012/05/04/2482328.html 在实际开发中LayoutInflater这个类还是非常有用的,它的作用 ...