Struts2中OGNL表达式的用法

OGNL的全称是Object Graph Navigation Language(对象图导航语言),它是一种强大的表达式语言,能通过简单一致的表达式语法来读取和设置Java对象的属性值,调用对象的方法,遍历整个对象的结构图,实现字段类型转换等功能。

一、为什么要使用OGNL

视图层的表达式语言通常是用来简化数据的访问操作,取代Java脚本代码,提供更清晰的视图层实现。比如,要获取user对象的age属性,利用OGNL表达式可以写成:

<s:property value="user.age"/>

而如果要换做Java脚本代码,则需要写成:

<%@ page import="com.chongqing.model.User" %>
<%
	User user = (User)request.getAttribute("user");
	String age = user.getAge();
	out.print(age);
%>

可以看出,利用OGNL表达式会更加清晰和简洁。

二、值栈(ValueStack)

OGNL有一个上下文(Context)的概念,说白了上下文就是一个MAP结构,它实现了Java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext ,它结构示意图如下:

|--request

|--application

OGNL  context ------ | ValueStack(值栈,它是根对象)

|--session

|--attr

|--parameters

当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。

访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session等

另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可

可以通过<s:debug></s:debug>标签在浏览器上看到Context的内容,其实OGNL表达式就是用来访问Context中的内容。

三、OGNL表达式

OGNL表达式的语法多且杂,要全部总结出来有点困难,这里我偷一点懒,通过一个例子来说明,以后查阅也会方便一些。

OgnlAction类:

  1 package com.chongqing.ognl;
  2
  3 import java.util.ArrayList;
  4 import java.util.HashMap;
  5 import java.util.HashSet;
  6 import java.util.List;
  7 import java.util.Map;
  8 import java.util.Set;
  9
 10 import com.opensymphony.xwork2.ActionSupport;
 11
 12 public class OgnlAction extends ActionSupport {
 13     private Cat cat;
 14     private Map<String, Dog> dogMap = new HashMap<String, Dog>();
 15
 16     private Set<Dog> dogs = new HashSet<Dog>();
 17
 18     private String password;
 19
 20     private User user;
 21     private String username;
 22
 23     private List<User> users = new ArrayList<User>();
 24
 25     public OgnlAction() {
 26         users.add(new User(1));
 27         users.add(new User(2));
 28         users.add(new User(3));
 29
 30         dogs.add(new Dog("dog1"));
 31         dogs.add(new Dog("dog2"));
 32         dogs.add(new Dog("dog3"));
 33
 34         dogMap.put("dog100", new Dog("dog100"));
 35         dogMap.put("dog101", new Dog("dog101"));
 36         dogMap.put("dog102", new Dog("dog102"));
 37
 38     }
 39
 40     public String execute() {
 41         return SUCCESS;
 42     }
 43
 44     public Cat getCat() {
 45         return cat;
 46     }
 47
 48     public Map<String, Dog> getDogMap() {
 49         return dogMap;
 50     }
 51
 52     public Set<Dog> getDogs() {
 53         return dogs;
 54     }
 55
 56     public String getPassword() {
 57         return password;
 58     }
 59
 60     public User getUser() {
 61         return user;
 62     }
 63
 64     public String getUsername() {
 65         return username;
 66     }
 67
 68     public List<User> getUsers() {
 69         return users;
 70     }
 71
 72     public String m() {
 73         return "hello";
 74     }
 75
 76     public void setCat(Cat cat) {
 77         this.cat = cat;
 78     }
 79
 80     public void setDogMap(Map<String, Dog> dogMap) {
 81         this.dogMap = dogMap;
 82     }
 83
 84     public void setDogs(Set<Dog> dogs) {
 85         this.dogs = dogs;
 86     }
 87
 88     public void setPassword(String password) {
 89         this.password = password;
 90     }
 91
 92     public void setUser(User user) {
 93         this.user = user;
 94     }
 95
 96     public void setUsername(String username) {
 97         this.username = username;
 98     }
 99
100     public void setUsers(List<User> users) {
101         this.users = users;
102     }
103 }

User类:

 1 package com.chongqing.ognl;
 2
 3 public class User {
 4     private int age = 8;
 5
 6     public User() {
 7
 8     }
 9
10     public User(int age) {
11         super();
12         this.age = age;
13     }
14
15
16     public int getAge() {
17         return age;
18     }
19
20     public void setAge(int age) {
21         this.age = age;
22     }
23
24     @Override
25     public String toString() {
26         return "user" + age;
27     }
28 }

Cat类:

 1 package com.chongqing.ognl;
 2
 3 public class Cat {
 4
 5     private Dog friend;
 6
 7     public Dog getFriend() {
 8         return friend;
 9     }
10
11     public void setFriend(Dog friend) {
12         this.friend = friend;
13     }
14
15     public String miaomiao() {
16         return "miaomiao";
17     }
18 }

Dog类:

 1 package com.chongqing.ognl;
 2
 3 public class Dog {
 4
 5     private String name;
 6
 7     public Dog() {
 8
 9     }
10
11     public Dog(String name) {
12         super();
13         this.name = name;
14     }
15
16     public String getName() {
17         return name;
18     }
19
20     public void setName(String name) {
21         this.name = name;
22     }
23
24     @Override
25     public String toString() {
26         return "dog: " + name;
27     }
28 }

S类:

1 package com.chongqing.ognl;
2
3 public class S {
4     public static String STR = "STATIC STRING";
5
6     public static String s() {
7         return "static method";
8     }
9 }

ognl.jsp:

<?xml version="1.0" encoding="GB18030" ?>
<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
<title>OGNL表达式语言学习</title>
</head>
<body>
	<ol>
		<%-- 访问普通方法和属性:
		1、通过域模型的方式只有传入参数,才会构造对象,或者直接在action中new也可以
		 --%>
		<li>访问值栈中的action的普通属性: username = <s:property value="username"/> </li>
		<li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user[‘age‘]"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:property value="user[age]"/>--%></li>
		<li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li>
		<li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li>
		<li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>
		<li>访问值栈中action的普通方法:<s:property value="m()" /></li>
		<hr />

		<%-- 访问静态方法和属性:
		1、OGNL表达式语言访问静态方法,需要在Struts2.xml配置allowStaticMethodAccess为true
		2、@@max(2,3)这种方式只能访问Math的静态方法
		 --%>
		<li>访问静态方法:<s:property value="@[email protected]()"/></li>
		<li>访问静态属性:<s:property value="@[email protected]"/></li>
		<li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>
		<hr />
		<li>访问普通类的构造方法:<s:property value="new com.chongqing.ognl.User(8)"/></li>
		<hr />

		<%-- 访问集合:
		1、{}大括号可以表示一个集合
		2、因为在Set中没有排序所以不能用下标访问
		3、访问容器的大小用方法size()和属性size都行
		 --%>
		<li>访问List:<s:property value="users"/></li>
		<li>访问List中某个元素:<s:property value="users[1]"/></li>
		<li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
		<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
		<li>访问Set:<s:property value="dogs"/></li>
		<li>访问Set中某个元素:<!--<s:property value="dogs[1]"/>--></li>
		<li>访问Map:<s:property value="dogMap"/></li>
		<li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap[‘dog101‘]"/> | <s:property value="dogMap[\"dog101\"]"/></li>
		<li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
		<li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
		<li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>
		<hr />

		<%-- 投影:
		1、投影其实就是对集合过滤选择
		2、?表示选取过滤后的所有元素
		3、^表示选取过滤后的第一个元素
		4、$表示选取过滤后的最后一个元素
		 --%>
		<li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li>
		<li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li>
		<li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li>
		<li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>
		<hr />
		<li>[]:<s:property value="[0].username"/></li>

	</ol>

	<s:debug></s:debug>
</body>
</html>

访问的URL为:

http://localhost:8080/Struts2_OGNL/ognl.action?username=u&password=p&user.age=11&cat.friend.name=oudy

结果为:

时间: 2024-10-10 05:11:22

Struts2中OGNL表达式的用法的相关文章

深入分析JavaWeb 48 -- Struts2中OGNL表达式与ValueStack

一.OGNL表达式 1.OGNL表达式介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的表达式语言. OGNL相对其它表达式语言具有下面几大优势: 1.支持对象方法调用,如xxx.doSomeSpecial(): 2.支持类静态的方法调用和值访问,表达式的格式: @[类全名(包括包路径)]@[方法名 | 值名],例如:@[email protected]('foo %s', '

struts2 与 OGNL 表达式,jsp中 利用ognl 在valuestack中取值

在Struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入ValueStack(实际上就是放到ValueStack的CompoundRoot中),所以Action对象是CompoundRoot中的一个元素.看下面的代码: public class UserAction { private String username; private Integer age; private boolean valid; //查看用户的详细信息 public String de

struts2中ognl标签详解

<body> <s:set name="age" value="61" /> <!-- if elseif else 参数test:决定标志里的内容是否显示的表达式,类型boolean 注:else标志没有这个参数 --> <h3>if语句</h3> <s:if test="{age>60}"> 老年人 </s:if> <s:elseif test=&

Struts2之OGNL表达式

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.Struts2框架使用OGNL作为默认 的表达式语言. 相对于EL表达式,它提供了平时我们需要的一些功能,如: 支持对象方法调用,如xxx.sayHello(); 支持类静态方法调用和常量值访问,表达式的格式为@[类全名(包括包路径)]@[方法名|值名],例如:@[email protected]('foo%s','bar')或@[email protected]_NAME;

struts2的OGNL表达式

基本概念: OGNL(Object Graph Navigation Language),是一种表达式语言.使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性.调用Java对象树的方法.同时能够自动实现必要的类型转化.如果我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁. OGNL的API看起来就是两个简单的静态方法: public static Object getValue( Object tree, Map

struts2中&lt;s:checkboxlist/&gt;的用法详解

Html代码 选择角色<br> <s:checkboxlist list="#request.roleuserList" listKey="roleId" listValue="roleName" value="#request.rolelist.{roleId}" name="roleIds"></s:checkboxlist> 说明: 其中#request.roleu

Struts2之 OGNL表达式和值栈

技术分析之OGNL表达式概述(了解)        1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写        * 所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象        * 通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能.它使用相同的表达式去存取对象的属性        2. Struts2框架使用OGNL作为默认的表达式语言 

Struts2:OGNL表达式详解

OGNL用于操作ValueStack中的数据.它负责两件事.第一是在接收HTTP请求时将请求中的字符串转换成Java中的类型,比如int.String等,并赋值给ValueStack上的JavaBean,第二是在页面渲染的时候,从ValueStack中获取属性,并将Java类型转换成字符串进行输出.整个过程如下图: (侵权可删) 在HTTP的请求参数中,可以包含OGNL表达式(这就是当初Struts2爆重大漏洞的原因了). user.name=xxx表示给user属性中的name属性进行赋值.

Struts2之OGNL表达式语言

1.OGNL是Object-Graph Navigation Language的缩写,是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能.其中OGNL用得最多的地方就是和Struts2的标签绑定,也可以在配置文件中通过${}使用OGNL表达式. 2.OGNL表达式中有几个常用的符号,下面介绍这三种符号的使用: (1).OGNL中$号的使用:第一种,可以在国际化资源文件中引用OGNL表达式.第二种,可以在st