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("@[email protected](username)", user);

}

public void testOgnl14() throws Exception{

User user = new User();

user.setUsername("wangwu");

//调用静态方法,注意使用全路径类名

Ognl.getValue("@[email protected](@[email protected](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("@[email protected](#list[1])", context,root);

Ognl.getValue("@[email protected](#intarray[2])", context,root);

Ognl.getValue("@[email protected](#mapvalue.listvalue[0])", context,root);

Ognl.getValue("@[email protected](#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

时间: 2024-10-10 04:08:34

ValueStack基础:OGNL的相关文章

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

(1)最近学习struts相框,我们在快乐struts强大.为了便于使用转发,但不了解详细的内部数据存储: (2)网上找了很多关于struts数据存储的原理,但我还没有找到一个具体的解释,本书上找到了 ValueStack和OGNL实现Struts2表单数据的存储原理 特分享给大家! (3)下面是部分截图:解说了关于struts框架中数据表单等的存储! watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font/5a6L5

ValueStack和OGNL实现Struts2表单数据的存储原理

(1)最近学习了struts框架,我们愉悦于struts的强大,方便转发器的使用,但是却不了解内部数据的具体存储: (2)在网上找了很多关于struts数据存储的原理,但是一直没有找到一个详细解说的,偶尔在一本书上找到了 ValueStack和OGNL实现Struts2表单数据的存储原理 特分享给大家! (3)以下是部分截图:讲解了关于struts框架中数据表单等的存储! 感觉这本书讲解的确实很好!需要的回复油箱地址发给你们!

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

Ognl常用标签:  1.s:debug 如果把该标签放入到s:iterator中可以看到当前正在迭代的元素的状态   2.s:property 1.输出 2.value属性:值能直接跟ognl表达式 3.如果value属性不写,则默认输出栈顶的元素    3:s:iterator标签 (1).iterator迭代Collection,Map,Object[],还可以以组合的形式迭代 (2).当前正在迭代的元素在栈顶 (3).如果value属性不写,则默认迭代栈顶的元素 (4).如果迭代的是ma

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

Ognl经常使用标签:  1.s:debug 假设把该标签放入到s:iterator中能够看到当前正在迭代的元素的状态   2.s:property 1.输出 2.value属性:值能直接跟ognl表达式 3.假设value属性不写.则默认输出栈顶的元素    3:s:iterator标签 (1).iterator迭代Collection,Map,Object[],还能够以组合的形式迭代 (2).当前正在迭代的元素在栈顶 (3).假设value属性不写,则默认迭代栈顶的元素 (4).假设迭代的是

OGNL、ValueStack、重构资费列表、Action基本原理

<span style="font-family: 微软雅黑, 'Times New Roman'; font-size: 24px; line-height: 24px; background-color: rgb(255, 255, 255);">1. OGNL</span> 1.1. OGNL介绍 1.1.1. 什么是OGNL Object Graph Navigation Language,是一门功能强大的表达式语言,类似于EL. 1.1.2. 为什么用

struts2.1.6教程四—二、OGNL与ValueStack(VS) (ActionContext 、ValueStack 、Stack Context

ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext.getContext() ValueStack 由OGNL框架实现 可以把它简单的看作一个栈(List) . Stack Object:放入stack中的对象,一般是action. Stack Context(map):stack上下文,它包含一系列对象,包括request/session/attr/application ma

[转]Struts2数据传输的背后机制:ValueStack(值栈)

1. 数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! 2. ValueStack基础:OGNL 要了解ValueStack,必须先理解OGNL(Object Graphic Navigatino Language)! OGNL是Struts2中使用的一种表达式语言,它可以: ①用于JSP的标签库中,以便能够方便的访问各种对象的属性: ②用于界面将参数传递到Action(并进行类型转换)中: ③用于struts2的配置文件中! 所以,非常有

[转] valuestack,stackContext,ActionContext.之间的关系

三者之间的关系如下图所示: ActionContext  一次Action调用都会创建一个ActionContext  调用:ActionContext context = ActionContext.getContext() ValueStack 由OGNL框架实现  可以把它简单的看作一个List Stack Object:放入stack中的对象,一般是action. Stack Context(map):stack上下文,它包含一些列对象,包括request/session/attr/ap

Struts2中的valuestack

值栈(ValueStack) Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是 OgnlContext),并将值栈设为OGNL的根对象. 我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的“标记”, 而引用上下文中的其他对象则需要使用“#”来标记.由于值栈是上下文中的根对 象,因此可以直接访问.那么对于值栈中的对象该如何访问呢?Struts2提供了一 个特殊的OGNLPropertyAccessor,它可以自动查找栈内的所有对象