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 ...
随机推荐
- iframe控件
function goTo(url) { document.getElementById("iframeid").src = url; //获得要显示的页面,当点击时就会在ifra ...
- Cacti 'graph_xport.php' SQL注入漏洞
漏洞版本: Cacti < 0.8.8b 漏洞描述: Bugtraq ID:66555 Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具. Cact ...
- BZOJ2542: [Ctsc2001]终极情报网
题解: 乘积最小只需要取对数.然后反向边就变成1/c,而不是-c了. 精度问题搞得我已经我想说什么了... 贴一份网上的pascal 代码: type ss=record x,y,c,r,next:l ...
- BZOJ2668: [cqoi2012]交换棋子
题解: 可以戳这里:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 其实自己yy一下就知道这样建图的正确性了. 感觉太神奇 ...
- acdream 小晴天老师系列——竖式乘法(简单穷举)
小晴天老师系列——竖式乘法 Time Limit: 4000/2000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) ...
- PSR-4——新鲜出炉的PHP规范
FIG 制定的PHP规范,简称PSR,是PHP开发的事实标准. PSR原本有四个规范,分别是: PSR-0 自动加载 PSR-1 基本代码规范 PSR-2 代码样式 PSR-3 日志接口 2013年底 ...
- Eclipse文件编码设置的问题
Eclipse中设置编码的方式 如果要使插件开发应用能有更好的国际化支持,能够最大程度的支持中文输出, 则最好使 Java文件使用UTF-8编码.然而,Eclipse工作空间(workspace)的缺 ...
- C++ 文件操作(CFile类)
原文:文件操作(CFile),C吉羊 一.Visual C++编程文件操作 有如下方法可进行操作: (1)使用标准C运行库函数,包括fopen.fclose.fseek等. (2)使用Win16下的文 ...
- 通过chrome识别手机端app元素--Chrome:inspector
现实中应该有这样一种情况,就是一个app只支持手机端使用,同时他又是hybrid的,那么其中的webview部分的元素属性如何去获得呢? 使用下面的方法可以解决这个问题: 调试 Android Chr ...
- QTP、LoadRunner、QC工具下载地址
QTP10.0工具下载地址:http://h30302.www3.hp.com/prdownloads/T6510-15063.zip?ordernumber=380454070&itemid ...