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表达式语言,能在运行 ...
随机推荐
- (从终端看linux-1)linux tty pty pts 概念 区别
基本概念: 1> tty(终端设备的统称):tty一词源于Teletypes,或者teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的东西,后来这东 ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)2----通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域
实现目的:动态加载dll,执行完毕之后可以随时卸载掉,并可以替换这些dll,以在运行中更新dll中的类. 其实就是通过应用程序域AppDomain加载和卸载程序集. 在这方面微软有篇文章http:// ...
- Oracle数据字典详解
学习笔记:oracle数据字典详解 --- 本文为TTT学习笔记,首先介绍数据字典及查看方法,然后分类总结各类数据字典的表和视图.然后列出一些附例. 数据字典系统表,保存在system表空间中. ...
- 职责链实现的apache.chain使用
其实职责链在老早就使用过了,以前在HW给Vodafone做金融项目的时候,使用职责链完成交易步骤,那时觉得这东西真好用,可以直接通过配置决定业务流程,现在终于有机会实践一下. 项目地址:h ...
- 深入理解Java虚拟机 - 虚拟机内存划分
在内存管理方面,Java相对于C和C++的区别在于Java具有内存动态分配以及垃圾收集技术,但平时我们很少去关注JVM的内存结构以及GC,在出现内存泄露或溢出方面的问题,排查工作将变得异常艰难. ...
- [Unity3d]小地图的制作
继续今天的学习心得,unity中小地图的制作,实现了小地图中红色小箭头代表场景中的主角,然后人物方向的转变,小地图中箭头也随之改变方向. 效果图 右上角就是小地图,上面有个红色小箭头就是代表主 ...
- IE中Ajax数据缓存的问题
在IE中,Ajax回来的数据会有缓存的现象发生,解决方式: 1,改变URL,每次请求加一个随机数参数Math.random()或者new Date().getTime(),这样IE会认为URL不一样, ...
- UVa 1210 (高效算法设计) Sum of Consecutive Prime Numbers
题意: 给出n,求把n写成若干个连续素数之和的方案数. 分析: 这道题非常类似大白书P48的例21,上面详细讲了如何从一个O(n3)的算法优化到O(n2)再到O(nlogn),最后到O(n)的神一般的 ...
- JS框架整理
1. Dojo (演示地址) Dojo是一个强大的面向对象JavaScript框架.主要由三大模块组成:Core.Dijit.DojoX.Core提供ajax,events,packaging,CSS ...
- [swustoj 856] Huge Tree
Huge Tree(0856) 问题描述 There are N trees in a forest. At first, each tree contains only one node as it ...