OGNL表达式

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

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的源代码,如下:

  1. public class OgnlContext extends Object implements Map
  2. {
  3. public static final String CONTEXT_CONTEXT_KEY = "context";
  4. public static final String ROOT_CONTEXT_KEY = "root";
  5. public static final String THIS_CONTEXT_KEY = "this";
  6. .......
  7. }

有一个特点是继承自Map接口

现在可以写一写其测试类:

  1. package com.gqx.ognl;
  2.  
  3. import ognl.Ognl;
  4. import ognl.OgnlContext;
  5. import ognl.OgnlException;
  6.  
  7. import org.junit.Test;
  8.  
  9. public class OgnlTest {
  10. /**
  11. * 使用Ognl表达式取值,取非根元素的值,必须要用"#"
  12. */
  13. @Test
  14. public void test() {
  15. //创建一个OgnlContext上下文对象
  16. OgnlContext context=new OgnlContext();
  17. //存放数据,继承自map接口,所以map形式存放
  18. context.put("name", "gqxing");
  19. //获取数据
  20. String value=(String) context.get("name");
  21. System.out.println(value);
  22. }
  23.  
  24. @Test
  25. public void test2() throws OgnlException {
  26. //创建一个OgnlContext上下文对象
  27. OgnlContext context=new OgnlContext();
  28. //存放数据,继承自map接口,所以map形式存放
  29. User user=new User();
  30. user.setId(101);
  31. user.setName("gqxing");
  32. context.put("user", user);
  33. //获取数据
  34. /*
  35. * 第一种方式:
  36. User value=(User) context.get("user");
  37. System.out.println(user.getName()+":"+user.getId());
  38. *
  39. *第二种方式
  40. *先构建一个ognl表达式,在解析表达式
  41. */
  42. //向非根元素取值是,要用"#"号
  43. Object ognl=Ognl.parseExpression("#user.id");
  44. Object value=Ognl.getValue(ognl, context, context.getRoot());
  45. System.out.println(value);
  46. }
  47.  
  48. /**
  49. * Ognl表达式语言语言取值,取根元素的值,不用带#号
  50. * @throws OgnlException
  51. */
  52. @Test
  53. public void test3() throws OgnlException {
  54. //创建一个OgnlContext上下文对象
  55. OgnlContext context=new OgnlContext();
  56. //存放数据,继承自map接口,所以map形式存放
  57. User user=new User();
  58. user.setId(101);
  59. user.setName("gqxing");
  60. context.put("user", user);
  61. //设置根元素,向根元素放数据
  62. context.setRoot(user);
  63. //获取数据(map)
  64. //向根元素取值是,直接写属性
  65. Object ognl=Ognl.parseExpression("id");
  66. Object value=Ognl.getValue(ognl, context, context.getRoot());
  67. System.out.println(value);
  68. }
  69.  
  70. /**
  71. * 获取属性之下的属性
  72. * @throws OgnlException
  73. */
  74. @Test
  75. public void test4() throws OgnlException {
  76. //创建一个OgnlContext上下文对象
  77. OgnlContext context=new OgnlContext();
  78. //存放数据,继承自map接口,所以map形式存放
  79. User user=new User();
  80. user.setId(101);
  81. user.setName("gqxing");
  82. context.put("user", user);
  83. //设置根元素,向根元素放数据
  84. context.setRoot(user);
  85. //获取数据(map)
  86. //向根元素取值是,直接写属性
  87. Object ognl=Ognl.parseExpression("address.province");
  88. Object value=Ognl.getValue(ognl, context, context.getRoot());
  89. System.out.println(value);
  90. }
  91.  
  92. /**
  93. * 静态方法调用
  94. * @throws OgnlException
  95. */
  96. @Test
  97. public void test5() throws OgnlException {
  98. OgnlContext context =new OgnlContext();
  99. //Ognl表达式语言,调用静态方法
  100. //Object ognl=Ognl.parseExpression("@Math@floor(5.6)");
  101. //由于Math类在开发中用的比较多,所以可以这样写
  102. Object ognl=Ognl.parseExpression("@@floor(5.6)");
  103. Object value=Ognl.getValue(ognl, context,context.getRoot());
  104. System.out.println(value);
  105. }
  106.  
  107. }

Struts2的值栈ValueStack

ValueStack即值栈对象,是整个数据存储的核心,或叫中转站。实现了该接口的OgnlValueStack类。
ValueStack特点
        ValueStack贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象. Struts2框架把 ValueStack 对象保存在名为 “struts.valueStack” 的request请求属性中,传入jsp页面。开发者只需通过ActionContext对象就可以直接去访问struts的其他关键对象,(ActionContext是专门给开发者使用的,便于学习和使用)

可以写一个Action来测试其中的关系

  1. package com.gqx.ognl;
  2.  
  3. import javax.servlet.ServletRequest;
  4.  
  5. import org.apache.struts2.ServletActionContext;
  6.  
  7. import com.opensymphony.xwork2.ActionContext;
  8. import com.opensymphony.xwork2.ActionSupport;
  9. import com.opensymphony.xwork2.util.ValueStack;
  10.  
  11. /**
  12. * struts的数据流转
  13. * @author GQXing
  14. *
  15. */
  16. public class OgnlDemo extends ActionSupport{
  17. @Override
  18. public String execute() throws Exception {
  19. //值栈对象存储数据的原理:
  20. ActionContext actionContext=ActionContext.getContext();
  21. ValueStack valueStack2=actionContext.getValueStack();
  22. System.out.println(valueStack2);
  23. return SUCCESS;
  24. }
  25.  
  26. public String test(){
  27. //获取值栈对象。方式一:
  28. ServletRequest request=ServletActionContext.getRequest();
  29. ValueStack valueStack=(ValueStack) request.getAttribute("struts.valueStack");
  30. //获取值栈对象。方式二
  31. ActionContext actionContext=ActionContext.getContext();
  32. ValueStack valueStack2=actionContext.getValueStack();
  33. System.out.println(valueStack==valueStack2); //true
  34. return SUCCESS;
  35. }
  36. }

加入断点调试,可以看到相应的变量值

可以先写这个程序来测试

  1. package com.gqx.ognl;
  2.  
  3. import java.util.Map;
  4.  
  5. import com.opensymphony.xwork2.ActionContext;
  6. import com.opensymphony.xwork2.ActionSupport;
  7. import com.opensymphony.xwork2.util.ValueStack;
  8.  
  9. public class OgnlDemo2 extends ActionSupport{
  10.  
  11. private User user=new User(101,"gqxing");
  12.  
  13. @Override
  14. public String execute() throws Exception {
  15. // TODO Auto-generated method stub
  16. ActionContext ac=ActionContext.getContext();
  17. Map<String, Object> map=(Map<String, Object>) ac.get("request");
  18. //映射数据
  19. map.put("request_data", "request_data");
  20. map.put("cn", "China");
  21. //ac.getContextMap().put("request_data", "request_data");
  22. ac.getSession().put("Session_data", "Session_data");
  23. ac.getApplication().put("Application_data", "Application_data");
  24. ValueStack vs=ac.getValueStack();
  25. /*********操作根元素的几种方法*********/
  26. // vs.push(new User(111,"hehe")); //入栈顶
  27. // vs.pop(); //栈顶元素出来
  28.  
  29. //map结构存储
  30. // vs.set("user1", new User(102,"Code"));
  31. // vs.set("user2", new User(103,"Hello"));
  32.  
  33. System.out.println(vs);
  34. return super.execute();
  35. }
  36. }

当用户在访问这个action的时候,action参数产生的临时数据都保存在ValueStack中,jsp页面要做出响应的反应,都是从这个ValueStack中取数据的。

ValueStack中相应的数据如下

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

创建一个action以及对应的实体配置

  1. package com.gqx.ognl;
  2.  
  3. import java.util.Map;
  4.  
  5. import com.opensymphony.xwork2.ActionContext;
  6. import com.opensymphony.xwork2.ActionSupport;
  7. import com.opensymphony.xwork2.util.ValueStack;
  8.  
  9. public class OgnlDemo2 extends ActionSupport{
  10.  
  11. private User user=new User(101,"gqxing");
  12. public void setUser(User user) {
  13. this.user = user;
  14. }
  15. public User getUser() {
  16. return user;
  17. }
  18.  
  19. @Override
  20. public String execute() throws Exception {
  21. // TODO Auto-generated method stub
  22. ActionContext ac=ActionContext.getContext();
  23. // Map<String, Object> map=(Map<String, Object>) ac.get("request");
  24. //映射数据
  25. // map.put("request_data", "request_data");
  26. // map.put("cn", "China");
  27. ac.getContextMap().put("request_data", "request_data");
  28. ac.getSession().put("Session_data", "Session_data");
  29. ac.getApplication().put("Application_data", "Application_data");
  30. ValueStack vs=ac.getValueStack();
  31. /*********操作根元素的几种方法*********/
  32. // vs.push(new User(111,"hehe")); //入栈顶
  33. // vs.pop(); //栈顶元素出来
  34.  
  35. //map结构存储
  36. // vs.set("user1", new User(102,"Code"));
  37. // vs.set("user2", new User(103,"Hello"));
  38.  
  39. System.out.println(vs);
  40. return super.execute();
  41. }
  42. }

在xml中配置:

  1. <action name="ognl2" class="com.gqx.ognl.OgnlDemo2">
  2. <result name="success">/ognl.jsp?name=${user.name}</result>
  3. </action>

jsp页面

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%@taglib uri="/struts-tags" prefix="s"%>
  3.  
  4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  5. <html>
  6. <head>
  7.  
  8. <title>My JSP 'index.jsp' starting page</title>
  9. <meta http-equiv="pragma" content="no-cache">
  10. <meta http-equiv="cache-control" content="no-cache">
  11. <meta http-equiv="expires" content="0">
  12.  
  13. </head>
  14.  
  15. <body>
  16.  
  17. <!-- 页面:必须要拿到ValueStack -->
  18. <br> 取根元素的值<br>
  19. <s:property value="user.id"/>
  20. <s:property value="user.name"/>
  21. <s:property value="user.address.province"/>
  22. <s:property value="user.address.city"/>
  23.  
  24. <br> 取非根元素的值<br>
  25. <s:property value="#request.cn"/>
  26. <s:property value="#request.request_data"/>
  27. <s:property value="#session.Session_data"/>
  28. <s:property value="#application.Application_data"/>
  29. <br> 通过attr来取非根元素的值<br>
  30. <!-- 自动查找request/session/application,找到后立即自动返回 -->
  31. <s:property value="#attr.cn"/>
  32. <s:property value="#attr.request_data"/>
  33. <s:property value="#attr.Session_data"/>
  34. <s:property value="#attr.Application_data"/>
  35. <br> 2、取非根元素的值<br>
  36. <!-- 这种方式只有在Request中可以用 -->
  37. <s:property value="#request_data"/>
  38.  
  39. <br>
  40. <!-- 获取请求的参数 -->
  41. <s:property value="#parameters.name"/>
  42. <!--struts的调试标签 ,可以观测值栈数据-->
  43. <s:debug></s:debug>
  44. </body>
  45. </html>

效果如图:

现在利用struts的list和map迭代学习:

先创建一个Action类

  1. package com.gqx.ognl;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import com.opensymphony.xwork2.ActionContext;
  9. import com.opensymphony.xwork2.ActionSupport;
  10.  
  11. public class OgnlDemo3 extends ActionSupport{
  12. @Override
  13. public String execute() throws Exception {
  14. List<User> list =new ArrayList<User>();
  15. Map<Integer, User> map=new HashMap<Integer, User>();
  16. //初始化
  17. for (int i = 0; i < 11; i++) {
  18. User user=new User(i,"gqxing"+i);
  19. list.add(user);
  20. map.put(user.getId(), user);
  21. }
  22. //保存在request
  23. ActionContext.getContext().getContextMap().put("list", list);
  24. ActionContext.getContext().getContextMap().put("map", map);
  25. /*不加警号
  26. ActionContext.getContext().getValueStack().push(arg0);
  27. */
  28.  
  29. return super.execute();
  30. }
  31. }

以及与其对应的jsp页面:

  1. <%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%@taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  3. <html>
  4. <head>
  5.  
  6. <title>My JSP 'index.jsp' starting page</title>
  7. <meta http-equiv="pragma" content="no-cache">
  8. <meta http-equiv="cache-control" content="no-cache">
  9. <meta http-equiv="expires" content="0">
  10. <style type="text/css">
  11. .odd{
  12. background-color: red;'
  13. }
  14. .even{
  15. background: blue;
  16. }
  17.  
  18. </style>
  19. </head>
  20.  
  21. <body>
  22. <br>1、list迭代
  23. <br>
  24. <table border="1">
  25. <tr>
  26. <td>编号</td>
  27. <td>名称</td>
  28. </tr>
  29. <s:iterator var="user" value="#request.list" status="st">
  30. <tr class=<s:property value="#st.even?'even':'odd'"/>>
  31. <td><s:property value="#user.id" /></td>
  32. <td><s:property value="#user.name" /></td>
  33. </tr>
  34. </s:iterator>
  35. </table>
  36. <br>1、map迭代
  37. <br>
  38. <table border="1">
  39. <tr>
  40. <td>编号</td>
  41. <td>名称</td>
  42. </tr>
  43. <s:iterator var="entry" value="#request.map" status="st">
  44. <tr class=<s:property value="#st.even?'even':'odd'"/>>
  45. <td><s:property value="#entry.key" /></td>
  46. <td><s:property value="#entry.value.name" /></td>
  47. </tr>
  48. </s:iterator>
  49. </table>
  50. <!-- Ognl表达式 可以取值,也可以动态创建集合-->
  51. <br>一、构建List集合<br>
  52. <s:iterator var="str" value="{'a','b'}">
  53. <s:property value="#str"/>
  54. <br>
  55. </s:iterator>
  56. <br>一、构建Map集合<br>
  57. <s:iterator var="en" value="#{'cn':'China','name':'gqxing' }">
  58. <s:property value="#en.key"/>
  59. <s:property value="#en.value"/>
  60. <br>
  61. </s:iterator>
  62.  
  63. </body>
  64. </html>

效果如图:

Ognl表达式语言的更多相关文章

  1. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  2. OGNL表达式语言网上转来的

    1.概念:OGNL是ObjectGraphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语言. 2.功能: ...

  3. Struts ognl表达式语言几个符号

    #  获取非根元素值  . 动态都建map集合 $  配置文件取值 %  提供一个ognl表达式运行环境 <%@ page language="java" import=&q ...

  4. Struts2中使用OGNL表达式语言访问静态方法和静态属性

    1.一定要在struts.xml配置文件中配置允许使用OGNL访问静态方法,否则不能使用OGNL访问静态方法 2.<s:property value="@com.gk.StaticTe ...

  5. Ognl表达式基本原理和使用方法

    Ognl表达式基本原理和使用方法 1.Ognl表达式语言 1.1.概述 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个 ...

  6. Spring表达式语言 之 5.1 概述 5.2 SpEL基础(拾叁)

    5.1  概述 5.1.1  概述 Spring表达式语言全称为"Spring Expression Language",缩写为"SpEL",类似于Struts ...

  7. 20160502-struts2入门--ognl表达式

    一.OGNL表达式语言 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语言 ...

  8. ValueStack背后的OGNL表达式

    原文地址:http://blog.csdn.net/li_tengfei/archive/2010/12/25/6098134.aspx 前言: Strut2的Action类通过属性可以获得所有相关的 ...

  9. 开涛spring3(5.1&5.2) - Spring表达式语言 之 5.1 概述 5.2 SpEL基础

    5.1  概述 5.1.1  概述 Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行 ...

随机推荐

  1. JS动画 | 用TweenMax实现收集水滴效果

    之前在CodePen上接触了TweenMax, 被它能做到的酷炫效果震撼了. (文末放了5个GSAP的效果GIF) 最近要做一个"收集水滴"的动效, 于是就试用了一下TweenMa ...

  2. linux查看某个端口是否被占用

    一个还算可以的:[root@benet ~]# netstat -nlptu |awk '{print $4,$7}' | grep 80:::80 2508/httpd这样更直观的显示出要查询的端口 ...

  3. Tiny4412汇编流水灯代码,Tiny4412裸机LED操作[1]

    从今天开始就正式进入到tiny4412的开发学习中了,今天主要看了一下Tiny4412的启动流程及存储器映射及Exynos4412数据手册,用汇编写了一个跑马灯程序(后续会有C语言版本的出来),先说一 ...

  4. Oracle EBS PO 收接事处理状态待定或错误

    PO接收后,发现在没有接收成功.在"事务处理状态汇总"查找到不是"待定"就是"错误",如下图:   对于事务处理状态"待定&quo ...

  5. 解决Eclipse导出javadoc乱码问题

    在Eclipse里 export 选 JavaDoc,在向导的最后一页的Extra JavaDoc Options 里填上参数即可 比如项目采用的是UTF-8的编码就填:-encoding UTF-8 ...

  6. [LOJ 1030] Discovering Gold

    B - Discovering Gold Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  7. c语言编译预处理和条件编译执行过程的理解

    在C语言的程序中可包括各种以符号#开头的编译指令,这些指令称为预处理命令.预处理命令属于C语言编译器,而不是C语言的组成部分.通过预处理命令可扩展C语言程序设计的环境. 一.预处理的工作方式 1.1. ...

  8. (5)jvm垃圾回收器相关垃圾回收算法

    引用计数法[原理]--->引用计数器是经典的也是最古老的垃圾收集防范.--->实现原理:对于对象A,只要有任何一个对象引用A,则计数器加1.当引用失效时,计数器减1.只要对象A的计数器值为 ...

  9. 【转】COCOS2D-X之不断变化的数字效果Demo

    我们在玩"天天爱消除"或"天天连萌"的时候,每玩一盘后会有一个游戏结果界面,上面有一个显示所得分数的效果.今天我们这个Demo就是要实现与之相近的效果. 一.我 ...

  10. guake默认快捷键

    toggle guake visibility   切换guake可见 :F12 toggle fullscreen   切换全屏幕 :F11 quit   退出 :Shift+Ctrl+Q new ...