學習Struts--Chap04:值棧和OGNL
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="@[email protected]"/><hr/> 13 OGNL訪問靜態方法: 14 <s:property value="@com.java[email protected]()"/> 15 </body> 16 </html>