Struts2中的OGNL详解



Struts2中的OGNL详解.首先了解下OGNL的概念:

OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。

此外,还得先需弄懂OGNL的一些知识:

1.OGNL表达式的计算是围绕OGNL上下文进行的。

OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。

上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。

2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:

3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。

4.值栈(ValueStack) :

可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。

Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。

5.调用ActionContext的put(key,value)放入的数据,需要使用#访问。

OGNL中重要的3个符号:#、%、$:

#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,需要时间的积累才渐渐弄清楚……

1.#符号

#符号的用途一般有三种。

— 访问非根对象属性,例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute(“msg”) 。

— 用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name==’pla1′}.{age}[0]。

— 用来构造Map,例如示例中的#{‘foo1′:’bar1′, ‘foo2′:’bar2′}。

2.%符号
%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值,这个类似js中的eval,很暴力。

3.$符号

$符号主要有两个方面的用途。

— 在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

— 在Struts 2框架的配置文件中引用OGNL表达式,例如:

1.
2.
3.
4. 10 5. 100 6. BAction-test校验:数字必须为${min}为${max}之间!
7.

8.

9.

下面通过代码对OGNL有更深的了解:

action类OgnlAction.java:

1.package com.tjcyjd.test.action;
2.
3.import java.util.Date;
4.import java.util.LinkedList;
5.import java.util.List;
6.
7.import javax.servlet.http.HttpServletRequest;
8.
9.import org.apache.struts2.ServletActionContext;
10.import org.apache.struts2.convention.annotation.Action;
11.import org.apache.struts2.convention.annotation.Namespace;
12.import org.apache.struts2.convention.annotation.ParentPackage;
13.import org.apache.struts2.convention.annotation.Result;
14.import org.apache.struts2.convention.annotation.Results;
15.import org.springframework.stereotype.Controller;
16.
17.import com.opensymphony.xwork2.ActionContext;
18.import com.opensymphony.xwork2.ActionSupport;
19.
20.@Controller
21.@Namespace(“/test”)
22.@ParentPackage(“struts-default”)
23.@Results( { @Result(name = “success”, location = “/other_test/showognl.jsp”),
24. @Result(name = “fail”, location = “/bbs/admin_login.jsp”),
25. @Result(name = “input”, location = “/bbs/admin_login.jsp”) })
26.public class OgnlAction extends ActionSupport {
27. private static final long serialVersionUID = -1494290883433357310L;
28. private List persons;
29.
30. @Action(“ognlTest”)
31. public String ognlTest() throws Exception {
32. // 获得ActionContext实例,以便访问Servlet API
33. ActionContext ctx = ActionContext.getContext();
34. // 存入application
35. ctx.getApplication().put(“msg”, “application信息”);
36. // 保存session
37. ctx.getSession().put(“msg”, “seesion信息”);
38. // 保存request信息
39. HttpServletRequest request = ServletActionContext.getRequest();
40. request.setAttribute(“msg”, “request信息”);
41. // 为persons赋值
42. persons = new LinkedList();
43. Person person1 = new Person();
44. person1.setName(“pla1″);
45. person1.setAge(26);
46. person1.setBirthday(new Date());
47. persons.add(person1);
48.
49. Person person2 = new Person();
50. person2.setName(“pla2″);
51. person2.setAge(36);
52. person2.setBirthday(new Date());
53. persons.add(person2);
54.
55. Person person3 = new Person();
56. person3.setName(“pla3″);
57. person3.setAge(16);
58. person3.setBirthday(new Date());
59. persons.add(person3);
60.
61. return SUCCESS;
62.
63. }
64.
65. public List getPersons() {
66. return persons;
67. }
68.
69. public void setPersons(List persons) {
70. this.persons = persons;
71. }
72.}

jsp页面showognl.jsp:

1.<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
2.
3.<%@ taglib prefix="s" uri="/struts-tags" %>
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

访问OGNL上下文和Action上下文

17.
18.
19.
20.

parameters:

21.
22.

request.msg:

23.
24.

session.msg:

25.
26.

application.msg:

27.
28.

attr.msg:

29.
30.


31.
32.

用于过滤和投影(projecting)集合

33.
34.

年龄大于20

35.
36.

    37.
    38.
    39.
    40. – 年龄:

    43.
    44.
    45.
    46.

47.
48.

姓名为pla1的年龄:

49.
50.


51.
52.

构造Map

53.
54.
55.
56.

The value of key “foo1″ is

57.
58.


59.
60.

%符号的用法

61.
62.
63.
64.

The value of key “foo1″ is

65.
66.

不使用%:

67.
68.

使用%:

69.
70.


71. <%
72. request.setAttribute("req", "request scope");
73. request.getSession().setAttribute("sess", "session scope");
74. request.getSession().getServletContext().setAttribute("app",
75. "aplication scope");
76. %>
77. 1.通过ognl表达式获取 属性范围中的值
78.

79.
80.

81.
82.

83.
84.

85.

86.
87. 2.通过ognl表达式创建list 集合 ,并且遍历出集合中的值
88.

89.
90.
91.


访问构造方法

调用普通类的构造方法:

1.5. 访问数组

获取List:

获取List中的某一个元素(可以使用类似于数组中的下标获取List中的内容):

获取Set:

获取Set中的某一个元素(Set由于没有顺序,所以不能使用下标获取数据):


×

获取Map:

获取Map中所有的键:

获取Map中所有的值:

获取Map中的某一个元素(可以使用类似于数组中的下标获取List中的内容):

获取List的大小:

访问集合 – 投影、选择(? ^ $)

利用选择获取List中成绩及格的对象:=60}.{username}”/>

利用选择获取List中成绩及格的第一个对象的username:

=60}.{username}”/>

利用选择获取List中成绩及格的最后一个对象的username:

=600}.{username}.size”/>

集合的伪属性

OGNL能够引用集合的一些特殊的属性,这些属性并不是JavaBeans模式,例如size(),length()等等. 当表达式引用这些属性时,OGNL会调用相应的方法,这就是伪属性.

集合

伪属性

Collection(inherited by Map, List & Set)

size ,isEmpty

List

iterator

Map

keys , values

Set

iterator

Iterator

next , hasNext

Enumeration

next , hasNext , nextElement , hasMoreElements

Lambda :[…]

格式::[…]

使用Lambda表达式计算阶乘:

OGNL中#的使用

#可以取出堆栈上下文中的存放的对象.

名称

作用

例子

parameters

包含当前HTTP请求参数的Map

#parameters.id[0]作用相当于

request.getParameter(“id”)

request

包含当前HttpServletRequest的属性(attribute)的Map

#request.userName相当于

request.getAttribute(“userName”)

session

包含当前HttpSession的属性(attribute)的Map

#session.userName相当于

session.getAttribute(“userName”)

application

包含当前应用的ServletContext的属性(attribute)的Map

#application.userName相当于

application.getAttribute(“userName”)

attr

用于按request > session > application顺序访问其属性(attribute)

获取Paraments对象的属性:

OGNL中%的使用

用%{}可以取出存在值堆栈中的Action对象,直接调用它的方法.

例如你的Action如果继承了ActionSupport .那么在页面标签中,用%{getText(‘key’)}的方式可以拿出国际化信息.

OGNL中$的使用

“$”有两个主要的用途

l 用于在国际化资源文件中,引用OGNL表达式

l 在Struts 2配置文件中,引用OGNL表达式

值栈

ValueStack对象。这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当 Struts 2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到 ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。

在Action中获得ValueStack对象:ActionContext.getContext().getValueStack()

l Top语法

使用Top获取值栈中的第二个对象:

l N语法

使用N获取值栈中的第二个对象:

l @语法

调用action中的静态方法: vs:值栈 1:表示第一个。

http://www.cnblogs.com/xly1208/archive/2011/11/19/2255500.html