1. 程式人生 > >學習Struts--Chap04:值棧和OGNL

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