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的更多相关文章

  1. ValueStack和OGNL达到Struts2形式的数据存储原理

    (1)最近学习struts相框,我们在快乐struts强大.为了便于使用转发,但不了解详细的内部数据存储: (2)网上找了很多关于struts数据存储的原理,但我还没有找到一个具体的解释,本书上找到了 ...

  2. 4. ValueStack 和 OGNL

    1. 属性哪来的 当我们通过Action处理完用户请求以后,可以直接在页面中获取到 action 的属性值. 如果我们在页面中尝试遍历四个域中的属性,会发现域中并没有username之类的Action ...

  3. struts2重点——ValueStack和OGNL

    一.值栈(ValueStack) 1.实现类:OGNLValueStack 2.对象栈:CompoundRoot(针对的是类级别的) (1)继承自 ArrayList —— 先进后出 (2)提供了栈的 ...

  4. 【Struts2五】ValueStack以及ognl表达式二(经常使用标签)

    Ognl经常使用标签:   1.s:debug       假设把该标签放入到s:iterator中能够看到当前正在迭代的元素的状态    2.s:property       1.输出       ...

  5. 19.OGNL与ValueStack(VS)-OGNL入门

    转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html 下面我们在com.asm.vo.User类中增加一个字段private Ad ...

  6. ValueStack背后的OGNL表达式

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

  7. 理解ValueStack的基本机制 OGNL表达式

    ValueStack基础:OGNL(Object Graphic Navigatino Language) OGNL是Struts2中使用的一种表达式语言. 它可以用于,在JSP页面,使用标签方便的访 ...

  8. struts2.1.6教程四、OGNL与ValueStack(VS)

    1.值栈入门 下面我们建立struts2ognl项目来练习ognl的使用. 步骤一.搭建strust2的开发环境 步骤二.建立LoginAction,主要代码如下: package com.asm; ...

  9. 浅析Struts2中的OGNL和ValueStack

    要了解Struts2与OGNL表达式的关系,我们必须先搞清楚以下三个概念: 1.  ActionContext它是Action运行的上下文环境,Action的多项设置都存放在次,我们每一次Action ...

随机推荐

  1. SSH2中memcached作为hibernate二级缓存

    一.安装memcached服务端 1. 下载memcached的windows稳定版,解压放某个盘下面,比如在c:\memcached2. 在CMD下输入 "c:\memcached\mem ...

  2. 学习面试题Day08

    1.TCP/IP协议的理解.     TCP/IP定义了电子设备(如计算机)连入因特网的标准,以及数据如何在它们之间传输的标准.它既是互联网中的基本通信语言或协议,也是局域网的通信协议.     TC ...

  3. 从ramdisk根文件系统启动Linux 二

    今天做了个试验,让Linux2.6.29.4从ramdisk根文件系统启动成功,总结一下.其中涉及的内容较多,很多东西不再详述,如需深入研究请查阅相关资料(百度或谷歌一下一大堆). 开发环境:Fedo ...

  4. A Fast Priority Queue Implementation of the Dijkstra Shortest Path Algorithm

    http://www.codeproject.com/Articles/24816/A-Fast-Priority-Queue-Implementation-of-the-Dijkst http:// ...

  5. Jenkin+TestNG进行自动化测试执行

    1.登陆jenkins'后,主页面有一个jenkins管理选项,进入该模块,对插件,系统进行配置.(安装一个extend choice parameter插件) 2.点击new item新建一个项目, ...

  6. <转>MySQL性能优化的最佳20+条经验

    http://coolshell.cn/articles/1846.html 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心 ...

  7. codeforce 600C - Make Palindrome

    练习string 最小变换次数下,且字典序最小输出回文串. #include <cstdio> #include <cstring> #include <cmath> ...

  8. flappy pig小游戏源码分析(4)——核心pig模块(未完待续)

    热身之后,我们要动点真格的了,游戏叫flappy pig,我们的pig终于要出场了. 老规矩,看看目录结构,读者对着目录结构好好回想我们已经讲解的几个模块: 其中game.js是游戏主程序,optio ...

  9. HW6.22

    import java.util.Arrays; public class Solution { public static void main(String[] args) { int[][] ch ...

  10. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...