struts2.1.6 ognl 05

  1. package com.demo.ognl;  
  2.   
  3. public class User {  
  4.     private int age = 8;  
  5.     public User() {}  
  6.     public User(int age) {  
  7.         super();  
  8.         this.age = age;  
  9.     }  
  10.     public int getAge() {  
  11.         return age;  
  12.     }  
  13.     @Override  
  14.     public String toString() {  
  15.         return "user" + age;  
  16.     }  
  17. }  

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

OGNL

 <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>     在struts2.1 设置 就是说明允许静态方法访问

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

  1. package com.demo.ognl;  
  2.   
  3. public class Dog {  
  4.     private String name;  
  5.     public Dog() {}  
  6.     public Dog(String name) {  
  7.         super();  
  8.         this.name = name;  
  9.     }  
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.     public void setName(String name) {  
  14.         this.name = name;  
  15.     }  
  16.       
  17.     @Override  
  18.     public String toString() {  
  19.         return "dog: " + name;  
  20.     }  
  21. }  
  1. package com.demo.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 = new Cat();  
  14.     private Map<String, Dog> dogMap = new HashMap<String,Dog>();  
  15.     private Set<Dog> dogs = new HashSet<Dog>();  
  16.     private String password;  
  17.     private User user;  
  18.     private String username;  
  19.     private List<User> users = new ArrayList<User>() ;  
  20.       
  21.     public OgnlAction() {  
  22.         users.add(new User(1));  
  23.         users.add(new User(2));  
  24.         users.add(new User(3));  
  25.   
  26.         dogs.add(new Dog("dog1"));  
  27.         dogs.add(new Dog("dog2"));  
  28.         dogs.add(new Dog("dog3"));  
  29.           
  30.         dogMap.put("dog100"new Dog("dog100"));  
  31.         dogMap.put("dog101"new Dog("dog101"));  
  32.         dogMap.put("dog102"new Dog("dog102"));  
  33.     }  
  34.       
  35.     @Override  
  36.     public String execute() throws Exception {  
  37.         return SUCCESS;  
  38.     }  
  39.       
  40.     public String m() {  
  41.         return "hello";  
  42.     }  
  43.       
  44.     public Cat getCat() {  
  45.         return cat;  
  46.     }  
  47.     public void setCat(Cat cat) {  
  48.         this.cat = cat;  
  49.     }  
  50.     public Map<String, Dog> getDogMap() {  
  51.         return dogMap;  
  52.     }  
  53.     public void setDogMap(Map<String, Dog> dogMap) {  
  54.         this.dogMap = dogMap;  
  55.     }  
  56.     public Set<Dog> getDogs() {  
  57.         return dogs;  
  58.     }  
  59.     public void setDogs(Set<Dog> dogs) {  
  60.         this.dogs = dogs;  
  61.     }  
  62.     public String getPassword() {  
  63.         return password;  
  64.     }  
  65.     public void setPassword(String password) {  
  66.         this.password = password;  
  67.     }  
  68.     public User getUser() {  
  69.         return user;  
  70.     }  
  71.     public void setUser(User user) {  
  72.         this.user = user;  
  73.     }  
  74.     public String getUsername() {  
  75.         return username;  
  76.     }  
  77.     public void setUsername(String username) {  
  78.         this.username = username;  
  79.     }  
  80.     public List<User> getUsers() {  
  81.         return users;  
  82.     }  
  83.     public void setUsers(List<User> users) {  
  84.         this.users = users;  
  85.     }  
  86.       
  87. }  


  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.         "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.         "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5. <struts>  
  6.     <package name="ognl" extends="struts-default">  
  7.         <action name="ognl" class="com.demo.ognl.OgnlAction">  
  8.             <result>/ognl.jsp</result>  
  9.         </action>  
  10.           
  11.         <action name="test" class="com.demo.ognl.TestAction">  
  12.             <result type="chain">ognl</result>  
  13.         </action>  
  14.     </package>  
  15. </struts>  

  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5.   
  6. <struts>  
  7.     <constant name="struts.enable.DynamicMethodInvocation" value="false"/>  
  8.     <constant name="struts.devMode" value="true"/>  
  9.     <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>  
  10.     <include file="/com/demo/ognl/ognl.xml"/>  
  11. </struts>  

  1. <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>  
  2. <%@taglib uri="/struts-tags" prefix="s" %>  
  3. <html>  
  4.   <head>  
  5.   </head>  
  6.   <body>  
  7.  <ol>  
  8.     <li>访问值栈中的action的普通属性: username = <s:property value="username"/></li>  
  9.     <li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/>   
  10.     | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/>   
  11.     | wrong: <%--<s:property value="user[age]"/>--%></li>  
  12.       
  13.     <li>访问值栈中对象的普通:(get set方法): <s:property value="cat.friend.name"/></li>  
  14.     <li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li>  
  15.     <li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()"/></li>  
  16.     <li>访问值栈中action的普通方法: <s:property value="m()"/></li>  
  17.     <hr/>  
  18.     <li>访问静态方法: <s:property value="@com.demo.ognl.S@s()"/></li>  
  19.     <li>访问静态属性: <s:property value="@com.demo.ognl.S@STR"/></li>     
  20.     <li>访问Math类的静态方法: <s:property value="@@max(2,3)"/></li>  
  21.     <hr/>  
  22.     <li>访问普通类的构造方法: <s:property value="new com.demo.ognl.User(8)"/></li>  
  23.     <hr/>  
  24.     <li>访问List:<s:property value="users"/></li>  
  25.     <li>访问List中某个元素: <s:property value="users[1]"/></li>  
  26.     <li>访问List中元素的某个属性的集合: <s:property value="users.{age}"/></li>  
  27.     <li>访问List中元素某个属性的集合中的特定值: <s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>  
  28.     <li>访问Set:<s:property value="dogs"/></li>  
  29.     <li>访问Set中某个元素: <s:property value="dogs[1]"/></li>  |取不到值是因为set是无顺序的、没意义  
  30.     <li>访问Map: <s:property value="dogMap"/></li>  | 重写了toString方法  
  31.     <li>访问Map中某个元素: <s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/>   
  32.         | <s:property value="dogMap[\"dog101\"]"/>  </li>  
  33.     <li>访问Map中所有的key: <s:property value="dogMap.keys"/></li>    
  34.     <li>访问Map中所有的value:<s:property value="dogMap.values"/></li>  
  35.     <li>访问容器的大小: <s:property value="dogMap.size()"/> | <s:property value="users.size"/></li>  
  36.     <hr/>  
  37.     <li>投影(过滤): <s:property value="users.{?#this.age==1}[0]"/></li>  
  38.     <li>投影:<s:property value="users.{^#this.age > 1}.{age}"/></li>  
  39.     <li>投影: <s:property value="users.{$#this.age > 1}.{age}"/></li>  
  40.     <li>投影: <s:property value="users.{$#this.age > 1}.{age} == null"/></Li>  
  41.     <hr/>  
  42.     <li>[]: <s:property value="[0].username"/></li>  
  43.  </ol>  
  44.    
  45.     <s:debug></s:debug>  
  46.   </body>  
  47. </html>  


8.1.2  OGNL语法

基本的OGNL语法是十分简单的,当然OGNL支持丰富的表达式,一般情况下,不用担心OGNL的复杂性。例如有一个man对象,该对象有一个name属性,那么使用OGNL来获得该name属性可以使用如下表达式:

man.name

OGNL表达式的基础单元称为导航链,简称为链。一个最简单的链由如下部分组成。
 —
属性名称:如上述示例中的name。
 —
方法调用:hashCode()返回当前对象的hash code。
 —
数组元素:listeners[0]返回当前对象的监听器列表中的第一个元素。

★ 说明 ★

OGNL表达式基于OGNL上下文中的当前对象,一个“链”将使用上一个“链”的处理结果,开发者可以任意扩展该链的长度,OGNL没有限制。

例如,一个OGNL表达式如下:

 name.toCharArray()[0].numericValue.toString() 


该表达式将按照如下步骤求值。

(1)获得OGNL Context中初始对象或者是根对象(root对象)的name对象。

(2)调用toCharArray()方法,返回一个String类型对象。

(3)获得该String对象的第一个字符。

(4)获得该字符的numericValue属性(该字符为一个Character对象,该对象有一个getNumericValue()方法,该方法返回一个Integer类型值)。

(5)将获得的Integer对象转换为一个String类型值(使用toString()方法)。

 

8.1.3  一个使用OGNL的示例

下面笔者以一个简单的示例来帮助读者理解OGNL表达式。使用OGNL表达式,需要在www.ognl.org网站下载一个ognl.jar插件包,将该文件复制到classpath路径下即可。建立一个复合类型,如代码8.1所示。

代码8.1  定义复合类型

package ch8;

import java.util.Date;//团队类public class Team {// 团队名称private String teamname;// 定义团队人员属性private Person person;// 团队人数private int personnum;//属性的getter和setter方法public String getTeamname() {return teamname;}public void setTeamname(String teamname) {this.teamname = teamname;}public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}public int getPersonnum() {return personnum;}public void setPersonnum(int personnum) {this.personnum = personnum;}}// 定义人员类class Person {// 姓名private String name;// 年龄private int age;// 人员出生日期private Date birthday;//属性的getter和setter方法public String getName() {return name;}public  void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}

代码8.1所示内容定义了两个复合类型:团队(team)和人员(person)类型。使用OGNL表达式示例,如代码8.2所示。

代码8.2  使用OGNL表达式示例

 package ch8;



import java.util.HashMap;
import java.util.Map;
import ognl.Ognl;
import ognl.OgnlException;
public class TestOGNL {
public static void main(String[] args) {
//定义一个Map对象
Map m = new HashMap();
//定义一个Team对象
Team team1 = new Team();
team1.setTeamname("团队1");
//定义一个Person对象
Person person1 = new Person();
person1.setName("pla1");
//添加team元素
team1.setPerson(person1);
//定义一个Team对象
Team team2 = new Team();
team2.setTeamname("团队2");
//定义一个Person对象
Person person2 = new Person();
person2.setName("pla2");
//添加team元素
team2.setPerson(person2);

//添加Map元素
m.put("team1", team1);
m.put("team2", team2);
try {
System.out.println(Ognl.getValue("team1.teamname", m));
System.out.println(Ognl.getValue("team2.person.name", m));
System.out.println(Ognl.getValue("teamname", team2));
System.out.println(Ognl.getValue("person.name", team2));
} catch (OgnlException e) {
}
}
}


代码8.2所示内容定义了一个Map类型的嵌套属性,如图8.1所示。

  

图8.1  嵌套属性示意图

运行该示例,控制器显示如下信息:

 团队1
pla2
团队2
pla2

★ 说明 ★

OGNL可以使用非常简单的表达式来访问多层嵌套属性,为开发者提供了一个有力的工具。

 

8.2  Struts 2的OGNL

OGNL是Struts 2框架的默认表达式语言,增强了Struts 2的数据访问能力,同时简化了代码。

8.2.1  Struts 2的OGNL表达式

标准的OGNL会设定一个根对象(root对象)。假设使用标准OGNL表达式来求值(不使用Struts 2的OGNL表达式),如果OGNL上下文(OgnlContextMap类型)有两个对象:foo对象,在OgnlContext中名称为foo;bar对象,在OgnlContext中名称为bar。同时foo对象被设置为根对象(root)。则利用下面的OGNL表达式求值:

// 返回foo.getBlah()
#foo.blah
//返回bar.getBlah()
#bar.blah
//返回foo.getBlah() ,因为foo为根对象
blah

★ 说明 ★

使用OGNL是非常简单的,如果要访问的对象不是根对象,如示例中的bar对象,则需要使用命名空间,用“#”来标识,如“#bar”;如果访问一个根对象,则不用指定命名空间,可以直接访问根对象的属性。

在Struts2框架中,值栈(Value Stack)就是OGNL的根对象,假设值栈中存在两个对对象实例:Man和Animal,这两个对象实例都有一个name属性,Animal有一个species属性,Man有一个salary属性,假设Animal在值栈的顶部,Man在Animal后面,下面的代码片断会帮助读者更好地理解OGNL表达式:

 // 调用animal.getSpecies()
species
// 调用man.getSalary()
salary
// 调用animal.getName(),因为Animal位于值栈的顶部
name


最后一行示例代码,返回的是animal.getName()返回值,即返回了Animal的name属性,因为Animal是值栈的顶部元素,OGNL将从顶部元素搜索,所以会返回Animal的name属性值。如果要获得Man的name值,则需要如下代码:

 man.name

Struts 2允许在值栈中使用索引,示例代码如下所示:

[0].name   // 调用animal.getName()
[1].name   // 调用man.getName()

★ 注意 ★

使用索引,并不是直接获得指定的元素,而是从指定的索引位置搜索。

Struts 2中的OGNL Context是ActionContext,如图8.2所示。

  

图8.2  Struts 2的OGNL Context结构示意图

★ 说明 ★

图8.2只是说明Struts 2的OGNL Context结构,实际上Context还包含其他对象。

由于值栈是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,则可以直接通过下面的代码访问值栈中的属性:

//获得值栈中的foo属性
${foo}

如果访问其他Context中的对象,由于不是根对象,在访问时,需要加#前缀。
 —
application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用Servlet的getAttribute("username")。
 —
session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
 —
request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.get力Attribute ("userName")。
 —
parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
 —
attr对象:用于按page-request-session-application顺序访问其属性。

8.2.2  OGNL的集合操作

如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。

可以使用如下代码直接生成一个List对象:

{e1,e2,e3…}

该OGNL表达式中,直接生成了一个List对象,该List对象中包含3个元素:e1、e2和e3。如果需要更多的元素,可以按照这样的格式定义多个元素,多个元素之间使用逗号隔开。

如下代码可以直接生成一个Map对象:

#{key1:value1,key2:value2,…}


Map类型的集合对象,使用key-value格式定义,每个key-value元素使用冒号标识,多个元素之间使用逗号隔开。

对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如代码8.3所示。

代码8.3  使用OGNL集合操作符

 
muhahaha


boo


muhahaha


boo

除了in和not in之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。
 —
?:获得所有符合逻辑的元素。
 —
^:获得符合逻辑的第一个元素。
 —
$:获得符合逻辑的最后一个元素。

例如代码:

person.relatives.{? #this.gender == 'male'}

该代码可以获得person的所有性别为male的relatievs集合。

8.2.3  Lambda表达式

OGNL支持基本的Lambda表达式语法,通过Lambda表达式语法,可以在OGNL中使用一些简单的函数。例如:

Fibonacci:

 

if n==0 return 0;
elseif n==1 return 1;
else return fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89

开发者可以使用Lambda表达式语法:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值