Struts 2 OGNL

1.什么是OGNL?

2.Struts 2 OGNL 表达式  

 

 ======================  华丽丽的分割线  ======================

 

 1.什么是OGNL?

 

 

1.0. OGNL简介:

OGNL(Object Graphic Navigation Language)对象导航语言,OGNL是一种功能强大的EL(Expression Language,表达式语言),可以通过简单的表达式来访问Java对象中的属性,而不是直接调用对象的获取和设置方法。这可以提供许多应用,比如:在XML文件中嵌入OGNL表达式语法,在JSP页面使用OGNL表达式语法,都将使界面更简洁。配合Struts标签(部分好用的标签)也使得实现某些功能(如:迭代)更容易。
 

1.1. OGNL基本思路:

OGNL表达式表达式的基础单元称为链(导航链),OGNL表达式基于OGNL上下文(Context,理解成环境)中的当前对象,一个链将使用上一个链的处理结果,开发者可以任意扩展该链的长度。

如:person.name.toString()

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

第一步,获取保存在OGNL Context中根对象(root对象)的person对象。

第二步,获取该对象的name属性。

第三步,将调用获取对象的属性的toString()方法.

(其实,这从表面看起来和java的调用方式没什么差别,只是多了OGNL Context用于保存各种数据)

 

1.2. OGNL优缺点:

优点:使用方便,功能丰富,可以实现EL,JSTL较难以实现的功能。

缺点:OGNL是Struts支持,并非SUN(被甲骨文收购 - -!#)自带,这就造成一个问题,移植性不好。另一个缺点,学多了容易和别的打乱。

 

 ======================  华丽丽的分割线  ======================

 

2.Struts 2 OGNL 表达式  

 

2.1. 演示OGNL的各种用法:

第一步,配置xml文件:struts.xml struts.ognl.allowStaticMethodAccess:设置其值为true,以便访问静态方法。

<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
<package name="ognl" namespace="/" extends="struts-default">
<action name="ognl" class="cn.hasone.test.ognl.OgnlTest">
<result>/ognl.jsp</result>
</action>
</package>

详情查看:http://www.cnblogs.com/loveis/articles/2005034.html

第二步,编写Action:OgnlTest.java

复制代码
1 package cn.hasone.test.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 cn.hasone.test.ognl.bean.User;
11
12 import com.opensymphony.xwork2.ActionSupport;
13
14 publicclass OgnlTest extends ActionSupport {
15 publicstatic String staticMethod() {
16 return"通过OGNL,可以直接访问action中的静态方法";
17 }
18
19 private String password;
20
21 // Domain方式
22 private User user;
23
24 private List<User> userList =new ArrayList<User>();
25
26 private Map<String,User> userMap =new HashMap<String,User>();
27
28 // 普通属性
29 private String username;
30
31 private Set<User> userSet =new HashSet<User>();
32
33 public OgnlTest(){
34 userList.add(new User("userList1"));
35 userList.add(new User("userList2"));
36
37 userSet.add(new User("userSet1"));
38 userSet.add(new User("userSet2"));
39
40 userMap.put("map1",new User("userMap1"));
41 userMap.put("map2",new User("userMap2"));
42 }
43
44 @Override
45 public String execute() throws Exception {
46 return SUCCESS;
47 }
48
49 public String getPassword() {
50 return password;
51 }
52
53 public User getUser() {
54 return user;
55 }
56
57 public String getUsername() {
58 return username;
59 }
60
61 public String normalMethod() {
62 return"通过OGNL,可以直接访问action中的方法";
63 }
64
65 publicvoid setPassword(String password) {
66 this.password = password;
67 }
68
69 publicvoid setUser(User user) {
70 this.user = user;
71 }
72
73 publicvoid setUsername(String username) {
74 this.username = username;
75 }
76
77 public List<User> getUserList() {
78 return userList;
79 }
80
81 publicvoid setUserList(List<User> userList) {
82 this.userList = userList;
83 }
84
85 public Map<String, User> getUserMap() {
86 return userMap;
87 }
88
89 publicvoid setUserMap(Map<String, User> userMap) {
90 this.userMap = userMap;
91 }
92
93 public Set<User> getUserSet() {
94 return userSet;
95 }
96
97 publicvoid setUserSet(Set<User> userSet) {
98 this.userSet = userSet;
99 }
100 }
复制代码

第三步,编写Domain(Bean): User.java

复制代码
1 package cn.hasone.test.ognl.bean;
2
3 publicclass User {
4 private String name;
5
6 public User() {}
7
8 public User(String name) {
9 this.name = name;
10 }
11
12 public String getName() {
13 return name;
14 }
15
16 publicvoid setName(String name) {
17 this.name = name;
18 }
19
20 @Override
21 public String toString() {
22 return"user is: "+this.name;
23 }
24
25 }
复制代码

第四步,编写JSP文件: ognl.jsp

复制代码
<%@ page language="java" import="java.util.*,java.net.URLDecoder" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>

<body>
访问action中的普通属性:username =
<s:property value="username"/></br>
访问action中的普通属性:password =
<s:property value="password"/></br>
访问action中的Domain属性:user.name =
<s:property value="user.name"/></br>
</br>
使用索引访问:
<s:property value="[0].username"/></br>
</br>
访问值栈中的普通方法:user.getClass() =
<s:property value="user.getClass()"/></br>
访问值栈中的普通方法:username.length() =
<s:property value="username.length()"/></br>
访问action中的普通方法:normalMethod() =
<s:property value="normalMethod()"/></br>
</br>
访问action中的静态方法:staticMethod() =
<s:property value="staticMethod()"/></br>
<!-- 访问静态方法也可写成如下:
访问action中的静态方法:staticMethod() = <s:property value="@cn.hasone.test.ognl.OgnlTest@staticMethod()"/></br>
-->
访问JAR包中的静态方法:staticMethod() =
<s:property value="@@max(2,3)"/></br>
<!-- 静态属性也可以,类同,略... -->
</br>
访问action中的List:
<s:property value="userList"/></br>
访问action中的List某个元素:
<s:property value="userList[1]"/></br>
访问action中的List元素的属性集合:
<s:property value="userList.{name}"/></br>
访问action中的List特定元素的属性:
<s:property value="userList[0].name"/></br>
</br>
<!-- 其他集合也类同,略,如:
<s:property value="userMap.keys"/>
<s:property value="userMap.map1"/>
注意:Set,Map无序,不能用下标方法取...
-->
<s:debug></s:debug>
</body>
</html>
复制代码

 

2.2. 对上述代码补充说明:

注意一:#符号的用途一般有三种:

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

第二,用于过滤集合,如示例中的persons.{?#this.age>20}。

第三,用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。

注意二:Struts 2允许在值栈中使用索引使用索引,并不是直接获得指定的元素,而是从指定的索引位置开始取属性值,若找不到则从索引号的下一位开始,直到有结果。

2.3. 投影(过滤)

{?#条件} // 满足这个条件的集合
如:users.{?#this.age==1}[0]
{^#条件} // 满足该条件的集合的第一个
{$#条件} // 满足该条件的集合的最后一个

原文地址:https://www.cnblogs.com/a1280055207/p/3145354.html