OGNL简介:
(1)OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。
struts2框架默认就支持Ognl表达式语言(所以struts必须引用的包:ognl.jar);
(2)struts2的ognl的作用:页面取值使用;
(3)OGNL和EL的区别:
EL表达式语言:用于页面取值,jsp页面取值的标准(默认可以直接使用,应用范围更加广泛);
OGNL表达式语言:struts2标签默认支持的表达式语言,必须配置struts标签使用,不能离开struts2标签直接使用;
(4)OGNL 有一个上下文(Context)概念,[OgnlContext对象:OgnlContext对象是ognl表达式语言的核心];
其实上下文就是一个MAP结构,它实现了 java.utils.Map 的接口。
(5)ognl表达式语言取值,取根元素的值,不用带#符号;ognl表达式语言取值,取非根元素的值,需要带#符号;
用一个OGNL和struts标签结合的实例演示一下struts的标签的强大功能:
1:第一还是引入struts2核心包,省略
2:创建一个实体类,用于测试显示在页面的信息,如User.java,源码如下所示:
代码语言:javascript复制 1 package com.bie.ognl;
2 /**
3 * @author BieHongLi
4 * @version 创建时间:2017年3月7日 下午8:45:27
5 *
6 */
7 public class User {
8
9 private int id;
10 private String name;
11 public int getId() {
12 return id;
13 }
14 public void setId(int id) {
15 this.id = id;
16 }
17 public String getName() {
18 return name;
19 }
20 public void setName(String name) {
21 this.name = name;
22 }
23 public User(int id, String name) {
24 super();
25 this.id = id;
26 this.name = name;
27 }
28
29
30 }
3:创建完成实体类之后就可以开始开发action,如OgnlAction.java,源码如下所示:
代码语言:javascript复制 1 package com.bie.ognl;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import com.opensymphony.xwork2.ActionContext;
9 import com.opensymphony.xwork2.ActionSupport;
10
11 /**
12 * @author BieHongLi
13 * @version 创建时间:2017年3月7日 下午8:43:00
14 *
15 */
16 public class OgnlAction extends ActionSupport{
17
18
19 private static final long serialVersionUID = 1L;
20 @Override
21 public String execute() throws Exception {
22 //测试迭代标签
23 List<User> list=new ArrayList<User>();
24 Map<Integer, User> map=new HashMap<Integer, User>();
25
26 //初始化
27 for(int i=1;i<11;i ){
28 User user=new User(i,"张三" i);
29
30 list.add(user);
31 map.put(user.getId(), user);
32 }
33
34 //保存list信息
35 ActionContext.getContext().getContextMap().put("list", list);
36 //保存map信息
37 ActionContext.getContext().getContextMap().put("map", map);
38
39
40 return "success";
41 }
42
43 }
4:开发完action,配置struts.xml文件,这里使用主次配置,所以这里配置ognl.xml,然后在struts.xml文件中引入ognl.xml配置文件即可:
代码语言:javascript复制 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
8 <package name="ognlpackage" extends="struts-default">
9 <action name="ognl" class="com.bie.ognl.OgnlAction">
10 <result name="success">ognl.jsp</result>
11 </action>
12 </package>
13
14
15 </struts>
5:最后书写ognl.jsp显示页面,用于显示信息,源码如下所示:
代码语言:javascript复制 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <%@ taglib prefix="s" uri="/struts-tags"%>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>ognl显示信息的页面</title>
9
10 <style type="text/css">
11 .odd{background-color:pink;}
12 .even{background-color:yellow;}
13 </style>
14 </head>
15 <body>
16
17 <h1>1:list显示信息</h1>
18 <table cellpadding="5" cellspacing="10">
19 <tr>
20 <th>编号</th>
21 <th>姓名</th>
22 <th>奇偶行</th>
23 </tr>
24 <s:iterator value="#request.list" var="user" status="us">
25 <tr class=<s:property value="#us.even?'even':'odd'"/>>
26 <td><s:property value="#user.id"/></td>
27 <td><s:property value="#user.name"/><br/></td>
28 <td><s:property value="#us.even" /></td>
29 </tr>
30 </s:iterator>
31 </table>
32 <h1>1:迭代map信息</h1>
33 <table cellpadding="5" cellspacing="10">
34 <tr>
35 <th>编号</th>
36 <th>编号2</th>
37 <th>姓名</th>
38 <th>奇偶行</th>
39 </tr>
40 <s:iterator value="#request.map" var="Muser" status="mu">
41 <tr class=<s:property value="#us.even?'even':'odd'"/>>
42 <td><s:property value="#Muser.value.id"/></td>
43 <!-- 迭代编号的两种方式 -->
44 <td><s:property value="#Muser.key"/></td>
45 <td><s:property value="#Muser.value.name"/><br/></td>
46 <td><s:property value="#mu.even" /></td>
47 </tr>
48 </s:iterator>
49 </table>
50 </body>
51 </html>
运行效果如下所示:
革命尚未成功,OGNL ko , go!!!
6:ValueStack, 即值栈对象(根元素的值存储在root中,非跟元素的值存储在context中)。
(1):值栈对象是整个struts数据存储的核心,或者叫中转站。
(2):用户每次访问struts的action,都会创建一个Action对象、值栈对象、ActionContext对象; 然后把Action对象放入值栈中; 最后再把值栈对象放入request中,传入jsp页面。
(3):(key: struts.valueStack); 开发者只需要通过ActionContext对象就可以访问struts的其他的关键对象。 (ActionContext是给开发者用的,便于学习与使用。)
代码语言:javascript复制 1 package com.bie.lesson09;
2
3
4 import javax.servlet.http.HttpServletRequest;
5
6 import org.apache.struts2.ServletActionContext;
7
8 import com.opensymphony.xwork2.ActionContext;
9 import com.opensymphony.xwork2.ActionSupport;
10 import com.opensymphony.xwork2.util.ValueStack;
11
12 /**
13 * @author Author:别先生
14 * @date Date:2017年9月23日 上午11:18:51
15 *
16 * struts的数据流转,如何从后台到页面
17 */
18 public class OgnlAction extends ActionSupport{
19
20 /**
21 *
22 */
23 private static final long serialVersionUID = 1L;
24
25 @Override
26 public String execute() throws Exception {
27 //获取值栈对象,方式一:
28 HttpServletRequest request = ServletActionContext.getRequest();
29 ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack");
30
31 //获取值栈对象,方式二:
32 ActionContext ac = ActionContext.getContext();
33 ValueStack vs2 = ac.getValueStack();
34
35 System.out.println(vs == vs2);
36
37 return SUCCESS;
38 }
39 }
(4)值栈的根元素和非根元素如何存储的关系:
(5)值栈操作根元素和非根元素的如何操作(ActionContext.getContext() = #,取值的时候理解):
代码语言:javascript复制package com.bie.lesson09;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @author Author:别先生
* @date Date:2017年9月23日 上午11:18:51
*
* struts的数据流转,如何从后台到页面
*/
public class OgnlAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
// 全局元素,根元素值
private User user = new User(1, "tom");
@Override
public String execute() throws Exception {
ActionContext ac = ActionContext.getContext();
//映射数据
//ac.getContextMap().put("request_data", "request_data");
// 数据存储request
@SuppressWarnings("unchecked")
Map<String,Object> map = (Map<String, Object>) ac.get("request");
map.put("request_data", "request_data");
map.put("cn", "China");
ac.getSession().put("session_data", "session_data");
ac.getApplication().put("application_data", "application_data");
// 二、值栈对象的存储数据的原理
ValueStack vs = ac.getValueStack();
/***************操作根元素的几种方法*****************/
// 设置数据: 入栈
// 栈顶
//vs.getRoot().push(new User(2, "jack"));
vs.push(new User(2, "jack"));
// 移除栈顶元素
vs.pop();
// 如何存储? map结构存储
vs.set("user1", new User(3, "张三"));
vs.set("user2", new User(4, "李四"));
System.out.println(vs);
return SUCCESS;
}
}
(6):页面获取元素的方法:
代码语言:javascript复制 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 <package name="ognlPackage" extends="struts-default">
8
9 <action name="ognl" class="com.bie.lesson09.OgnlAction">
10 <result name="success">success.jsp?userName=${#request.request_data}</result>
11 </action>
12 </package>
13
14 </struts>
15
代码语言:javascript复制 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <%@ taglib prefix="s" uri="/struts-tags"%>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>struts2 hello </title>
9 </head>
10 <body>
11
12 <h1>hello world struts2</h1>
13
14 <h1>${requestScope.request_data }</h1>
15 <h1>${sessionScope.session_data }</h1>
16 <h1>${applicationScope.application_data }</h1>
17
18 <!-- 页面: 必须要拿到ValueStack -->
19 <h1>根元素的值:</h1>
20 <s:property value="user.id"/><br/>
21 <s:property value="user.name"/><br/>
22 <s:property value="user.address"/><br/>
23 <s:property value="user.address.provice"/><br/>
24 <s:property value="user.address.city"/><br/>
25
26 <br/><br/>
27 <!-- 非根元素的值 -->
28 <s:property value="#request.cn"/><br/>
29 <s:property value="#session.session_data"/><br/>
30 <s:property value="#application.application_data"/>
31
32 <br/><br/>
33 <!-- 自动找request/session/application,找到后立刻返回 -->
34 <s:property value="#attr.cn"/><br/>
35 <s:property value="#attr.session_data"/><br/>
36 <s:property value="#attr.application_data"/><br/>
37
38 <br/><br/>
39 <!-- 获取请求的参数数据 -->
40 <s:property value="#parameters.userName"/>
41
42
43
44 <!-- struts的调试标签:可以观测值栈数据 -->
45 <s:debug></s:debug>
46 </body>
47 </html>
代码语言:javascript复制 1 package com.bie.lesson09;
2 /**
3 * @author Author:别先生
4 * @date Date:2017年9月23日 下午5:20:46
5 *
6 *
7 */
8 public class Address {
9
10 private String provice;
11 private String city;
12 public String getProvice() {
13 return provice;
14 }
15 public void setProvice(String provice) {
16 this.provice = provice;
17 }
18 public String getCity() {
19 return city;
20 }
21 public void setCity(String city) {
22 this.city = city;
23 }
24 public Address(String provice, String city) {
25 super();
26 this.provice = provice;
27 this.city = city;
28 }
29 public Address() {
30 super();
31 }
32
33
34 }