1、值栈的介绍
1.1 值栈的介绍:
值栈是对应每一个请求对象的数据存储中心,struts2会给每一个请求对象创建一个值栈,我们大多数情况下不需要考虑值栈在哪里,里面有什么,只需要去获取自己需要的数据就可以了,这样就大大的降低了开发人员的工作量和逻辑复杂性。
1.2 值栈的作用:
值栈能够线程安全的为每一个请求对象提供公共的数据存取服务。它可以统一管理页面和action之间的数据,供action、result、interceptor等使用。值栈和请求时一一对应的,也是唯一对应的,每一个请求有且只有唯一的一个值栈。不同的请求,值栈也不一样,值栈封装了一次请求所有操作的相关数据。正是因为值栈和请求的对应关系,因而值栈能保证每个请求访问数据时的线程安全。
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"/> 13 <s:property value="student.age"/><hr/> 14 OGNL访问List集合对象: 15 <s:property value="students[0].name"/> 16 <s:property value="students[0].age"/><br/> 17 <s:property value="students[1].name"/> 18 <s:property value="students[1].age"/><hr/> 19 OGNL访问Map集合对象: 20 <s:property value="studentMap['boy'].name"/> 21 <s:property value="studentMap['boy'].age"/><br/> 22 <s:property value="studentMap['girl'].name"/> 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>