学习Struts--Chap05:值栈和OGNL

1、值栈的介绍

1.1 值栈的介绍:

  值栈是对应每一个请求对象的数据存储中心,struts2会给每一个请求对象创建一个值栈,我们大多数情况下不需要考虑值栈在哪里,里面有什么,只需要去获取自己需要的数据就可以了,这样就大大的降低了开发人员的工作量和逻辑复杂性。

1.2 值栈的作用:

  值栈能够线程安全的为每一个请求对象提供公共的数据存取服务。它可以统一管理页面和action之间的数据,供actionresultinterceptor等使用。值栈和请求时一一对应的,也是唯一对应的,每一个请求有且只有唯一的一个值栈。不同的请求,值栈也不一样,值栈封装了一次请求所有操作的相关数据。正是因为值栈和请求的对应关系,因而值栈能保证每个请求访问数据时的线程安全。

1.3 值栈包含的内容:

  值栈分为狭义范围上的值栈和广义范围上的值栈。

  • 狭义范围上的值栈:狭义值栈中存放着一些OGNL可以存取访问的数据,主要是指:
    •  action实例,这样就可以通过OGNL来访问action实例中的属性的值
    • OGNL表达式运算的值
    • OGNL表达式产生的中间变量,比如Struts2标签,在JSP中使用标签,可以访问值栈中的数据。
  • 广义范围上的值栈:指的是ActionContext对象,actioncontext对象是action运行的上下文,每个actioncontext都是一个容器,包含着action运行所需要的数据,比如参数,会话等。
    • 请求参数中的数据:#parameters
    • 请求作用域中的数据:#request
    • 会话作用域中的数据:#session
    • 应用程序中的数据:#application

2、OGNL的介绍

2.1、OGNL的概述

  OGNL是对象图导航语言(Object-Graph Navigation Languaged)的英文缩写,是一种功能强大的表达式语言,通过简单一致的表达式语法,可以存取Java对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型的转化功能。它使用相同的表达式去存取对象的属性。如果把表达式看作一个带有语义的字符串,那么OGNL就是这个语义字符串与java对象之间沟通的桥梁。

2.2、OGNL的三要素

  表达式:OGNL就是根据表达式去对象中取值,所有的OGNL操作都是指对表达式解析并执行操作的过程。表达式用于指明此次OGNL操作要做什么。表达式就是一个带有语法含义的字符串,这个字符串规定了操作的类型和操作的内容。

  根对象(ROOT):Root对象可以理解为OGNL的操作对象,表达式规定了“做什么”,而Root对象则规定了“对谁执行操作"。OGNL称为对象图导航语言,所谓对象图,就是以任意对象为根,通过OGNL可以访问这个对象关联的其他所有对象。

  Context对象:OGNL的取值需要一个上下文环境,通过设置Root对象,OGNL就可以对root对象进行取值或者写值等操作,root对象所在的环境就是OGNL的上下文环境(Context)。上下文环境规定了OGNL的要执行的操作在哪里进行”。上下文环境Context是一个map类型的对象,在表达式中访问Context中的对象,需要使用”#”号加上对象名称,即“#对象名称”的形式。

3、OGNL访问VauleStack数据的操作

在展示界面取出值栈中的数据:

1 <body>
2 Name:<s:property  value="name" /><br/>
3 Age:<s:property  value="age" />
4 </body>

在Action中设置数据:

1     @Override
2     public String execute() throws Exception {
3         ActionContext actionContext = ActionContext.getContext();
4         ValueStack valueStack = actionContext.getValueStack();
5         valueStack.set("name", "baozi(ValueStack)");
6         valueStack.set("age", 24);
7         return SUCCESS;
8     }

4、OGNL访问ActionContext数据的操作

4.1、请求参数中的数据:#parameters 请求参数 request.getParameter(...)

4.2、请求作用域中的数据:#request 请求作用域中的数据 request.getAttribute(...)

4.3、会话作用域中的数据:#session 会话作用域中的数据 session.getAttribute(...)

4.4、应用程序作用域中的数据:#application 应用程序作用域中的数据 application.getAttribute(...)

4.5、#attr的用法:#attr 按照 page request session application 顺序查找值

在Action中设置数据:

 1 package com.java1234.action;
 2 import java.util.Map;
 3 import com.opensymphony.xwork2.Action;
 4 import com.opensymphony.xwork2.ActionContext;
 5 
 6 public class HelloAction2 implements Action {
 7     
 8     @Override
 9     public String execute() throws Exception {
10         ActionContext actionContext = ActionContext.getContext();
11 
12         // 在Action中设置session值
13         Map<String, Object> session = actionContext.getSession();
14         session.put("name", "张三(Session)");
15         session.put("age", 17);
16 
17         // 在Action中设置application值
18         Map<String, Object> application = actionContext.getApplication();
19         application.put("name", "李四(application)");
20         application.put("age", 24);
21         return SUCCESS;
22     }
23 
24 }

 在struts.xml中配置映射关系:

 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="helloWorld" extends="struts-default">
 7       <action name="hello" class="com.java1234.action.HelloAction2">
 8           <result name="success">success2.jsp</result>
 9       </action> 
10   </package>
11 </struts>

 在展示界面取出值栈中的数据:

 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>Insert title here</title>
 9 <%
10     request.setAttribute("name", "BaoZi(parameters)");
11     request.setAttribute("age", 11);
12 %>
13 </head>
14 <body>
15 请求参数中的数据:<s:property value="#parameters.name"/><br/>
16 <s:property value="#parameters.age"/><hr/>
17 请求作用域中的数据:<s:property value="#request.name"/><br/>
18 <s:property value="#request.age"/><hr/>
19 session作用域中的数据:<s:property value="#session.name"/><br/>
20 <s:property value="#session.age"/><hr/>
21 application作用域中的数据:<s:property value="#application.name"/><br/>
22 <s:property value="#application.age"/><br/>
23 </body>
24 </html>

 访问地址:localhost:8080/HeadFirstStruts2Chap01/hello?name=HeiHei&age=15

5、OGNL访问复杂对象

5.1、访问javaBean对象

5.2、访问集合对象

5.3、访问Map对象

Student对象:

 1 package com.java1234.model;
 2 
 3 public class Student {    
 4     private String name;
 5     private int age;    
 6     public Student() {
 7         super();
 8         // TODO Auto-generated constructor stub
 9     }    
10     public Student(String name, int age) {
11         super();
12         this.name = name;
13         this.age = age;
14     }    
15     public String getName() {
16         return name;
17     }
18     public void setName(String name) {
19         this.name = name;
20     }
21     public int getAge() {
22         return age;
23     }
24     public void setAge(int age) {
25         this.age = age;
26     }    
27     
28 }

在Action中设置数据:

 1 package com.java1234.action;
 2 import java.util.ArrayList;
 3 import java.util.HashMap;
 4 import java.util.List;
 5 import java.util.Map;
 6 
 7 import com.java1234.model.Student;
 8 import com.opensymphony.xwork2.Action;
 9 
10 public class HelloAction3 implements Action {
11     
12     //定义一个JavaBean对象的引用变量:
13     private Student student;
14     //定义一个List<Student>对象的引用变量:
15     private List<Student> students;    
16     //定义一个Map<String, Student>对象的引用变量:
17     private Map<String, Student> studentMap;
18     
19     
20     public Map<String, Student> getStudentMap() {
21         return studentMap;
22     }
23     public void setStudentMap(Map<String, Student> studentMap) {
24         this.studentMap = studentMap;
25     }
26     public List<Student> getStudents() {
27         return students;
28     }
29     public void setStudents(List<Student> students) {
30         this.students = students;
31     }
32     public Student getStudent() {
33         return student;
34     }
35     public void setStudent(Student student) {
36         this.student = student;
37     }
38 
39     @Override
40     public String execute() throws Exception {
41         //在action中给javaBean对象设置值
42         student = new Student("xiaohong", 10);
43         
44         //在action中给list集合设置值
45         students = new ArrayList<Student>();
46         students.add(new Student("xiaoqing", 17));
47         students.add(new Student("xiaohua", 16));
48         
49         //在action中给Map对象设置值
50         studentMap = new HashMap<String, Student>();
51         studentMap.put("boy", new Student("jianguo", 5));
52         studentMap.put("girl", new Student("xiaoxiang", 4));
53         return SUCCESS;
54     }
55 
56 }

在struts.xml中配置映射关系:同上边OGNL访问ActionContext数据的操作使得配置文件一样

在展示界面取出值栈中的数据:

 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>Insert title here</title>
 9 </head>
10 <body>
11 OGNL访问javaBean对象:
12 <s:property value="student.name"/>&nbsp;&nbsp;&nbsp;
13 <s:property value="student.age"/><hr/>
14 OGNL访问List集合对象:
15 <s:property value="students[0].name"/>&nbsp;&nbsp;&nbsp;
16 <s:property value="students[0].age"/><br/>
17 <s:property value="students[1].name"/>&nbsp;&nbsp;&nbsp;
18 <s:property value="students[1].age"/><hr/>
19 OGNL访问Map集合对象:
20 <s:property value="studentMap['boy'].name"/>&nbsp;&nbsp;&nbsp;
21 <s:property value="studentMap['boy'].age"/><br/>
22 <s:property value="studentMap['girl'].name"/>&nbsp;&nbsp;&nbsp;
23 <s:property value="studentMap['girl'].age"/><hr/>
24 </body>
25 </html>

访问地址:localhost:8080/HeadFirstStruts2Chap01/hello

6、OGNL访问静态属性和方法

创建一个包含静态属性和静态方法的类:MyStatic

 1 package com.java1234.common;
 2 
 3 public class MyStatic {
 4 
 5     public static final String str = "OGNL访问静态属性!";
 6     
 7     public static String print() {
 8         return "OGNL访问静态方法!";
 9     }
10 }

在配置文件中开启允许静态方法执行:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

在ognl_static.jsp页面展示:

 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>Insert title here</title>
 9 </head>
10 <body>
11 OGNL访问静态属性:
12 <s:property value="@com.java1234.common.MyStatic@str"/><hr/>
13 OGNL访问静态方法:
14 <s:property value="@com.java1234.common.MyStatic@print()"/>
15 </body>
16 </html>
原文地址:https://www.cnblogs.com/BaoZiY/p/10161776.html