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 ...
随机推荐
- [ahu 1248] NBA Finals
NBA Finals Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MBTotal Submission: 251 ...
- 网站资料收集 主要查看js的学习部分
1.Asp.Net MVC3.0基本的简单的可能都会用,更深入的使用还需加深研究,之后希望对MVC4.0和5.0进行对比学习,暂时看到@葡萄城控件技术团队博客的MVC5系列正在继续http://www ...
- jquery-autocomplete 参数说明
minChars (Number): 在触发autoComplete前用户至少需要输入的字符数.Default: 1,如果设为0,在输入框内双击或者删除输入框内内容时显示列表 * width (Num ...
- 交易的成功 = 60%的资金管理 + 40%出入场信号 zt
交易的成功 = 60%的资金管理 + 40%出入场信号. 资金管理 = 60%的风险分散 + 40%的适度重或轻仓. 出入场信号 = 60%的出场信号 + 40%的入场信号. 交易的成功 = 36 ...
- HDU 5607 graph 矩阵快速幂 + 快速幂
这道题得到了学长的助攻,其实就是一个马尔科夫链,算出一步转移矩阵进行矩阵快速幂就行了,无奈手残 这是我第一回写矩阵快速幂,写的各种毛病,等到调完了已经8点44了,交了一发,返回PE,(发现是少了换行) ...
- 富文本HTML编辑器UEditor
Baidu百度开源富文本HTML编辑器UEditor JS代码网 发表于: 2013-10-30 分类:HTML编辑器 点击:2133 UEditor是由百度web前端研发部开发所见即所得富文本H ...
- SQL注入攻击及防范
一.什么是SQL注入1.SQL注入的定义 SQL注入(SQL Injection) 利用了程序中的SQL的漏洞,进行攻击的方法. 2.SQL注入举例 1)利用SQL语法错误获取数据库表的结构 ...
- 相当管用了 mstha插件
http://www.i-magical.com/2010/04/feizhuliu-kill-virus-mshta-exe/ 非主流杀毒 – mshta.exe Vincent | Apr 23, ...
- [转载]mac下homebrew的使用
该文转自:https://www.zybuluo.com/phper/note/87055 mac系统也是基于unix的系统,所以也继承类很多unix的特性,包括软件的编译,安装等.ubuntu下有快 ...
- DTD - Attributes
In a DTD, attributes are declared with an ATTLIST declaration. Declaring Attributes An attribute dec ...