ValueStack基础:OGNL
ValueStack基础:OGNL
要了解ValueStack,必须先理解OGNL(Object Graphic Navigatino Language)!
OGNL是Struts2中使用的一种表达式语言,它可以用于JSP的标签库中,以便能够方便的访问各种对象的属性;它用于界面将参数传递到Action(并进行类型转换)中;它还可以用于struts2的配置文件中!所以,非常有必要理解OGNL的基本机制。
Root对象
OGNL称为对象图导航语言。所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象。如:
package cn.com.leadfar.struts2.actions; public class User { private String username; private Group group; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } } |
package cn.com.leadfar.struts2.actions; public class Group { private String name; private Organization org; public String getName() { return name; } public void setName(String name) { this.name = name; } public Organization getOrg() { return org; } public void setOrg(Organization org) { this.org = org; } } |
package cn.com.leadfar.struts2.actions; public class Organization { private String orgId; public String getOrgId() { return orgId; } public void setOrgId(String orgId) { this.orgId = orgId; } } |
上面三个类,描述了通过一个User对象,可以导航到Group对象,进而导航到Organization对象,以User对象为根,一个对象图如下所示:
User(root)
-- username
-- group
-- name
-- org
-- orgId
在真实的环境下,这个对象图可能会极其复杂,但是通过基本的getters方法,都应该能够访问到某个对象的其它关联对象。【对象图的导航,必须通过getters方法进行导航】
下述代码将创建一个User对象,及其相关的一系列对象:
User user = new User(); Group g = new Group(); Organization o = new Organization(); o.setOrgId("ORGID"); g.setOrg(o); user.setGroup(g); |
如果通过JAVA代码来进行导航(依赖于getters方法),导航到Organization的orgId属性,如下所示:
//用JAVA来导航访问 user.getGroup().getOrg().getOrgId(); |
【注意:导航的目的,是为了获取某个对象的值或设置某个对象的值或调用某个对象的方法!】
【注意:OGNL表达式语言的真正目的,是为了在那些不能写JAVA代码的地方执行JAVA代码,或者是为了更方便地执行JAVA代码】
利用OGNL进行导航的代码如下:
//利用OGNL表达式访问 String value = (String)Ognl.getValue("group.org.orgId", user); |
Ognl.getValue()方法的第一个参数,就是一条OGNL表达式,第二个参数是指定在表达式中需要用到的root对象!
完整代码如下:
public void testOgnl01() throws Exception{ User user = new User(); user.setUsername("张三"); //利用OGNL表达式访问user对象的username属性 String value = (String)Ognl.getValue("username", user); log(value); } public void testOgnl02() throws Exception{ User user = new User(); Group g = new Group(); Organization o = new Organization(); o.setOrgId("ORGID"); g.setOrg(o); user.setGroup(g); //用JAVA来导航访问 log(user.getGroup().getOrg().getOrgId()); //利用OGNL表达式访问 String value = (String)Ognl.getValue("group.org.orgId", user); log(value); } public void testOgnl03() throws Exception{ User user = new User(); Group g = new Group(); Organization o = new Organization(); o.setOrgId("ORGID"); g.setOrg(o); user.setGroup(g); //用JAVA来导航访问 log(user.getGroup().getOrg().getOrgId()); //也可以在表达式中使用#root来代表root对象 String value = (String)Ognl.getValue("#root.group.org.orgId", user); log(value); } private void log(Object o){ System.out.println(o); } |
Context对象
在OGNL的表达式中,有可能需要访问到多个毫不相干的对象,这时候,我们需要给OGNL传递一个Map类型的对象,把表达式中需要用到的对象放到Map中即可!这个Map对象,称为context。
要在表达式中访问到context中的对象,需要使用“#对象名称”的语法规则。
如:
public void testOgnl04() throws Exception{ User user = new User(); user.setUsername("张三"); Group g = new Group(); Organization o = new Organization(); o.setOrgId("ORGID"); g.setOrg(o); user.setGroup(g); User user2 = new User(); user2.setUsername("李四"); /** * 所谓context其实就是一个Map类型的对象。主要是因为在OGNL中,不支持多个root对象,那么 * 如果需要在表达式中访问更多毫不相干的对象时,只能通过一个Map来把这些对象统一传递给OGNL。 */ Map context = new HashMap(); context.put("u1", user); context.put("u2", user2); //在表达式中需通过“#+对象的名称”来访问context中的对象 //如果表达式中没有用到root对象,那么可以用任意一个对象代表root对象! String value = (String)Ognl.getValue("#u1.username + ',' + #u2.username", context,new Object()); log(value); } public void testOgnl05() throws Exception{ User user = new User(); user.setUsername("张三"); Group g = new Group(); Organization o = new Organization(); o.setOrgId("ORGID"); g.setOrg(o); user.setGroup(g); User user2 = new User(); user2.setUsername("李四"); User user3 = new User(); user3.setUsername("王五"); Map context = new HashMap(); context.put("u1", user); context.put("u2", user2); //给OGNL传递root对象及context对象,以便解释对应的表达式 String value = (String)Ognl.getValue("#u1.username + ',' + #u2.username + ',' + username", context,user3); log(value); } |
利用OGNL表达式进行赋值
OGNL表达式也可以用于赋值操作。
public void testOgnl06() throws Exception{ User user = new User(); //调用setValue()方法来进行赋值 //第一个参数:OGNL表达式 //第二个参数:root对象 //第三个参数:要赋的值 Ognl.setValue("username", user, "张三"); log(user.getUsername()); } public void testOgnl07() throws Exception{ User user = new User(); Map context = new HashMap(); context.put("u", user); //调用setValue()方法来进行赋值 //第一个参数:OGNL表达式 //第二个参数:context对象 //第三个参数:root对象 //第四个参数:要赋的值 Ognl.setValue("#u.username", context, new Object(), "张三"); log(user.getUsername()); } public void testOgnl08() throws Exception{ User user = new User(); Map context = new HashMap(); context.put("u", user); //利用赋值符号"="来进行赋值 Ognl.getValue("#u.username = '李四'", context, new Object()); log(user.getUsername()); } public void testOgnl09() throws Exception{ User user1 = new User(); User user2 = new User(); Map context = new HashMap(); context.put("u1", user1); context.put("u2", user2); //在一个表达式中可以用逗号分隔,同时执行多个表达式 Ognl.getValue("#u1.username = '李四',#u2.username='王五'", context, new Object()); log(user1.getUsername()); log(user2.getUsername()); } |
利用OGNL调用对象的方法
//************************* OGNL调用对象的方法 *****************************// public void testOgnl10() throws Exception{ User user = new User(); //如果是调用root对象的方法,可以直接使用方法的名称来调用方法 Integer value = (Integer)Ognl.getValue("addSomething(1,1)", user); log(value); } public void testOgnl11() throws Exception{ User user = new User(); user.setUsername("李四"); //如果是调用root对象的方法,可以直接使用方法的名称来调用方法 String value = (String)Ognl.getValue("getUsername()", user); log(value); } public void testOgnl12() throws Exception{ User user = new User(); Ognl.getValue("setUsername('王五')", user); String value = (String)Ognl.getValue("getUsername()", user); log(value); } //************************* OGNL调用静态方法和变量 *********************// public void testOgnl13() throws Exception{ User user = new User(); user.setUsername("王五"); //调用静态变量 //注意:out是System中的静态变量,out是PrintStream类型的一个对象 //而println()则是out这个对象中的实例方法(不是静态方法) //调用静态方法,需要在类名和变量名前面加上@来调用,对于实例方法,用"."来调用 Ognl.getValue("@System@out.println(username)", user); } public void testOgnl14() throws Exception{ User user = new User(); user.setUsername("wangwu"); //调用静态方法,注意使用全路径类名 Ognl.getValue("@System@out.println(@cn.com.leadfar.utils.Utils@toUpperCase(username))", user); } |
利用OGNL访问数组、集合对象
public void testOgnl15() throws Exception{ Object root = new Object(); Map context = new HashMap(); //利用OGNL创建java.util.List对象 List list = (List)Ognl.getValue("{123,'xxx','kdjfk'}", context, root); context.put("list", list); //利用OGNL创建数组 int[] intarray = (int[])Ognl.getValue("new int[]{23,45,67}", context, root); context.put("intarray", intarray); //利用OGNL表达式创建java.util.Map对象 Map mapvalue = (Map)Ognl.getValue("#{'listvalue':#list,'intvalue':#intarray}", context, root); context.put("mapvalue", mapvalue); //利用OGNL表达式访问这些数组和集合对象 Ognl.getValue("@System@out.println(#list[1])", context,root); Ognl.getValue("@System@out.println(#intarray[2])", context,root); Ognl.getValue("@System@out.println(#mapvalue.listvalue[0])", context,root); Ognl.getValue("@System@out.println(#mapvalue['intvalue'][0])", context,root); } public void testOgnl16() throws Exception{ List root = new ArrayList(); User user1 = new User(); user1.setUsername("张三"); User user2 = new User(); user2.setUsername("李四"); root.add(user1); root.add(user2); //如果root对象是List类型 log(Ognl.getValue("#root[0].username", root)); log(Ognl.getValue("#root[1].username", root)); } |
更多的特性,请参考官方的文档
OGNL官方文档地址:http://www.opensymphony.com/ognl/html/LanguageGuide/index.html
ValueStack基础:OGNL的更多相关文章
- ValueStack和OGNL达到Struts2形式的数据存储原理
(1)最近学习struts相框,我们在快乐struts强大.为了便于使用转发,但不了解详细的内部数据存储: (2)网上找了很多关于struts数据存储的原理,但我还没有找到一个具体的解释,本书上找到了 ...
- 4. ValueStack 和 OGNL
1. 属性哪来的 当我们通过Action处理完用户请求以后,可以直接在页面中获取到 action 的属性值. 如果我们在页面中尝试遍历四个域中的属性,会发现域中并没有username之类的Action ...
- struts2重点——ValueStack和OGNL
一.值栈(ValueStack) 1.实现类:OGNLValueStack 2.对象栈:CompoundRoot(针对的是类级别的) (1)继承自 ArrayList —— 先进后出 (2)提供了栈的 ...
- 【Struts2五】ValueStack以及ognl表达式二(经常使用标签)
Ognl经常使用标签: 1.s:debug 假设把该标签放入到s:iterator中能够看到当前正在迭代的元素的状态 2.s:property 1.输出 ...
- 19.OGNL与ValueStack(VS)-OGNL入门
转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html 下面我们在com.asm.vo.User类中增加一个字段private Ad ...
- ValueStack背后的OGNL表达式
原文地址:http://blog.csdn.net/li_tengfei/archive/2010/12/25/6098134.aspx 前言: Strut2的Action类通过属性可以获得所有相关的 ...
- 理解ValueStack的基本机制 OGNL表达式
ValueStack基础:OGNL(Object Graphic Navigatino Language) OGNL是Struts2中使用的一种表达式语言. 它可以用于,在JSP页面,使用标签方便的访 ...
- struts2.1.6教程四、OGNL与ValueStack(VS)
1.值栈入门 下面我们建立struts2ognl项目来练习ognl的使用. 步骤一.搭建strust2的开发环境 步骤二.建立LoginAction,主要代码如下: package com.asm; ...
- 浅析Struts2中的OGNL和ValueStack
要了解Struts2与OGNL表达式的关系,我们必须先搞清楚以下三个概念: 1. ActionContext它是Action运行的上下文环境,Action的多项设置都存放在次,我们每一次Action ...
随机推荐
- BZOJ_1027_[JSOI2007]_合金_(计算几何+Floyd求最小环)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1027 共三种金属,\(m\)种材料,给出每种材料中三种金属的占比. 给出\(n\)种合金的三种 ...
- vijos1067守望者的逃离
裸的矩阵乘法,我却调了一上午……弱到爆啊…… 不过最终辛苦没有白费,我终于彻底搞懂了 要注意几点: 一.必须构造出前几项 二.用矩阵乘法算法之后还要手工算答案,利用首先算好的前几项 三.想好自己构造的 ...
- POJ 3140-Contestants Division(树形dp)
题意: n给节点的树,分成两个联通分支,使它们大小的绝对值最小,求这个最小值. 分析: 分成两个联通分支,即删除一条边,开始看到m(边数)和n(点数)没什么关系,但题目说的是一棵树,则m==n-1,求 ...
- POJ3279 Fliptile 枚举+简单搜索
题意:一个矩阵,每个点1或0,然后每次翻一个点,它周围上下左右(包括自己)1->0,0->1,问最少翻几次可以矩阵全是0,忽略题目说的字典序 分析:枚举第一行所有的情况,然后下面几行也随之 ...
- e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector
Node.js已经出来了许多年载,至今才开始接触.周未在家闲来无事,一时心血来潮,Google了大量的文章,经过实验,终于可以把整个环境给搭起来, 废话不多话,请看步骤. 特别注意, 本文章是针对Wi ...
- QT中使用 slot 传递 opencv 中得Mat对象以及 使用多线程集成开源代码。
关于 slot传递 Mat 对象 以前一直是使用 Qtimer 定时器,设定超时后读取 dialog 对象的 Mat成员实现在 UI 里显示图像,发现这样对以后集成其他面向过程的代码增加了复杂度. 所 ...
- 富文本HTML编辑器UEditor
Baidu百度开源富文本HTML编辑器UEditor JS代码网 发表于: 2013-10-30 分类:HTML编辑器 点击:2133 UEditor是由百度web前端研发部开发所见即所得富文本H ...
- [原]《打造未来的Java》视频笔记
[Date]2013-09-28 [Author]wintys (wintys@gmail.com) http://wintys.cnblogs.com [Content]: 1.Java7新特性 1 ...
- MFC定时器
比较简单,在程序中可以找到原型. 在程序中我们经常要使用定时刷新的功能,典型的应用是在信息管理系统中表单要跟着数据库中的数据变动.MFC提供了定时器来完成这个功能. ================= ...
- grails2.3.11第一课
以指令的方式Getting Started 1. 创建一个项目 grails create-app HelloGrails 2. 因为我环境变量中配置的jdk是1.8的,所以我要把这个项目搞到IDEA ...