本博客的目的:①總結自己的學習過程,相當於學習筆記 ②將自己的經驗分享給大家,相互學習,互相交流,不可商用
內容難免出現問題,歡迎指正,交流,探討,可以留言,也可以通過以下方式聯系。
本人互聯網技術愛好者,互聯網技術發燒友
微博:伊直都在0221
QQ:951226918
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.關於 值棧
1).helloworld 時,${productName} 讀取productName 值,實際上該屬性不在request 等域對象中,而是從值棧中獲取的。
2).valueStack:可以從ActionContext 中獲取值棧對象,值棧分為兩個邏輯部門,
> Map 棧( ContextMap ):實際上是OgnlContext 類型,是一個Map,也是多ActionContext的一個引用。里面保存着各種MaprequsetMap,sessionMap,parameterMap,applicationMap,attr
Struts 會把下面這些映射壓入 ContextMap 中
parameters: 該 Map 中包含當前請求的請求參數
request: 該 Map 中包含當前 request 對象中的所有屬性
session: 該 Map 中包含當前 session 對象中的所有屬性
application:該 Map 中包含當前 application 對象中的所有屬性
attr: 該 Map 按如下順序來檢索某個屬性: request, session, application
> 對象棧( ObjectStack ):實際是CompoundRoot類型,是一個使用了ArrayList定義的棧,里面保存着和當前Action實例相關的對象。是一個數據結構意義的棧
ValueStack(值棧): 貫穿整個 Action 的生命周期(每個 Action 類的對象實例都擁有一個 ValueStack 對象). 相當於一個數據的中轉站. 在其中保存當前 Action 對象和其他相關對象.
Struts 框架把 ValueStack 對象保存在名為 “struts.valueStack” 的請求屬性中
2.OGNL
1)在 JSP 頁面上可以可以利用 OGNL(Object-Graph Navigation Language: 對象-圖導航語言) 訪問到值棧(ValueStack) 里的對象屬性.
2)若希望訪問值棧中 ContextMap 中的數據, 需要給 OGNL 表達式加上一個前綴字符 #. 如果沒有前綴字符 #, 搜索將在 ObjectStack 里進行.
3)Struts2利用s:property 標簽和OGNL 表達式來讀取值棧中的屬性值
>對於對象棧:讀取的是對象棧中的某一個對象的屬性值
>map棧:request,session,application 的一個屬性值 或 一個請求參數的值
①讀取對象棧中的對象的屬性:
>若想訪問 Object Stack 里面某個對象的屬性。可以使用一下幾種形式之一:
推薦第一種: object.propertyName; object['propertyName']; object["propertyName"];
>ObjectStack 里的對象可以通過一個從零開始的下標來引用. ObjectStack 里的棧頂對象可以用 [0] 來引用,它下面的那個對象可以用 [1] 引用.
[0].message
>[n] 的含義從第n 個開始搜索,而不只是搜索第n 個對象
>若從棧頂對象開始搜索,則可以省略下標部門:message
>結合s:property 標簽:<s:property value="message" /> 等同 <s:property value="[0].message" />
注意:默認情況下,Action對象會被Struts2 自動的放到值棧的棧頂
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>detail page</title>
9 </head>
10 <body>
11
12 <s:debug></s:debug>
13 <br><br>
14 ProductName:${productName } 15 <br><br>
16 ProductDesc:${productDesc } 17 <br><br>
18
19 ProductPrice:<s:property value="[1].productPrice"/> //使用標簽進行訪問值棧
20 <!-- ProductPrice:${productPrice } -->
21 <br><br>
22
23
24 </body>
25 </html>
Product.java
1 package com.jason.struts2; 2 3 import com.opensymphony.xwork2.ActionContext; 4 import com.opensymphony.xwork2.util.ValueStack; 5 6 public class Product { 7 8 private Integer productId; 9 private String productName; 10 private String productDesc; 11 12 private double productPrice; 13 14 15 16 public String save(){ 17 18 System.out.println(this); 19 //1.獲取值棧 20 ValueStack valueStack = ActionContext.getContext().getValueStack(); 21 22 //2.創建 Test 對象,並對其賦值 23 Test test = new Test(); 24 test.setProductDesc("testProductDesc"); 25 test.setProductName("testProductName"); 26 27 //3.把Test 對象壓入 值棧的棧頂 28 valueStack.push(test); 29 30 return "success"; 31 } 32 33 34 @Override 35 public String toString() { 36 return "Product [productId=" + productId + ", productName=" 37 + productName + ", productDesc=" + productDesc 38 + ", productPrice=" + productPrice + "]"; 39 } 40 41 public Integer getProductId() { 42 return productId; 43 } 44 45 public void setProductId(Integer productId) { 46 this.productId = productId; 47 } 48 49 public String getProductName() { 50 return productName; 51 } 52 53 public void setProductName(String productName) { 54 this.productName = productName; 55 } 56 57 public String getProductDesc() { 58 return productDesc; 59 } 60 61 public void setProductDesc(String productDesc) { 62 this.productDesc = productDesc; 63 } 64 65 public double getProductPrice() { 66 return productPrice; 67 } 68 69 public void setProductPrice(double productPrice) { 70 this.productPrice = productPrice; 71 } 72 73 74 75 76 }
Test.java
1 package com.jason.struts2; 2
3 public class Test { 4 private String productName; 5 private String productDesc; 6 public String getProductName() { 7 return productName; 8 } 9 public void setProductName(String productName) { 10 this.productName = productName; 11 } 12 public String getProductDesc() { 13 return productDesc; 14 } 15 public void setProductDesc(String productDesc) { 16 this.productDesc = productDesc; 17 } 18
19
20 }
struts.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 6 <struts> 7 8 <package name="default" namespace="/" extends="struts-default"> 9 10 <action name="product-save" class="com.jason.struts2.Product" method="save"> 11 <result name="success">/details.jsp</result> 12 </action> 13 14 </package> 15 16 </struts>
② 讀取 Context Map 里的對象的屬性
>若想訪問 ContextMap 里的某個對象的屬性, 可以使用以下幾種形式之一
推薦第一種: #object.propertyName; #object['propertyName']; #object["propertyName"];
>示例:
返回 session 中的 code 屬性: #session.code
返回 request 中的 customer 屬性的 name 屬性值: #request.customer.name
返回域對象(按 request, session, application 的順序)的 lastAccessDate 屬性: #attr.lastAccessDate
Product.java
1 package com.jason.struts2; 2
3 import java.util.Map; 4
5 import org.apache.struts2.interceptor.RequestAware; 6 import org.apache.struts2.interceptor.SessionAware; 7
8 import com.opensymphony.xwork2.ActionContext; 9 import com.opensymphony.xwork2.util.ValueStack; 10
11 public class Product implements RequestAware,SessionAware{ 12
13 private Integer productId; 14 private String productName; 15 private String productDesc; 16 private double productPrice; 17
18
19
20 public String save(){ 21
22 System.out.println(this); 23 //1.獲取值棧
24 ValueStack valueStack = ActionContext.getContext().getValueStack(); 25
26 //2.創建 Test 對象,並對其賦值
27 Test test = new Test(); 28 test.setProductDesc("testProductDesc"); 29 test.setProductName("testProductName"); 30
31 //3.把Test 對象壓入 值棧的棧頂
32 valueStack.push(test); 33 sessionMap.put("product", this); 34 requestMap.put("test", test); 35
36 return "success"; 37 } 38
39
40 @Override 41 public String toString() { 42 return "Product [productId=" + productId + ", productName="
43 + productName + ", productDesc=" + productDesc 44 + ", productPrice=" + productPrice + "]"; 45 } 46
47 public Integer getProductId() { 48 return productId; 49 } 50
51 public void setProductId(Integer productId) { 52 this.productId = productId; 53 } 54
55 public String getProductName() { 56 return productName; 57 } 58
59 public void setProductName(String productName) { 60 this.productName = productName; 61 } 62
63 public String getProductDesc() { 64 return productDesc; 65 } 66
67 public void setProductDesc(String productDesc) { 68 this.productDesc = productDesc; 69 } 70
71 public double getProductPrice() { 72 return productPrice; 73 } 74
75 public void setProductPrice(double productPrice) { 76 this.productPrice = productPrice; 77 } 78
79
80 private Map<String, Object> sessionMap; 81 public void setSession(Map<String, Object> arg0) { 82 this.sessionMap = arg0; 83
84 } 85
86
87 private Map<String,Object> requestMap; 88 public void setRequest(Map<String, Object> arg0) { 89 this.requestMap = arg0; 90
91 } 92
93
94
95
96 }
details.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>detail page</title>
9 </head>
10 <body>
11
12 <s:debug></s:debug>
13 <br><br>
14 ProductName:${productName } 15 <br><br>
16 ProductDesc:${productDesc } 17 <br><br>
18
19 ProductPrice:<s:property value="[1].productPrice"/>
20 <!-- ProductPrice:${productPrice } -->
21 <br><br>
22
23
24 ProductDesc1:${sessionScope.product.productName } 25 <s:property value="#session.product.productName"/> <!-- 通過標簽讀取屬性-->
26 <br><br>
27
28
29 ProductDesc2:${requestScope.test.productName } 30 <s:property value="#request.test.productName"/>
31 <br><br>
32
33 </body>
34 </html>
input.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7 <title>input page</title>
8 </head>
9 <body>
10
11 <form action="product-save.action" method="post">
12 ProductName:<input type="text" name="productName"/>
13 <br><br>
14
15 ProductDesc:<input type="text" name="productDesc"/>
16 <br><br>
17
18 ProductPrice:<input type="text" name="productPrice"/>
19 <br><br>
20
21 <input type="submit" value="submit" />
22 </form>
23 </body>
24 </html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="product-save" class="com.jason.struts2.Product" method="save">
<result name="success">/details.jsp</result>
</action>
</package>
</struts>
③調用字段和方法,數組
>可以利用 OGNL 調用
任何一個 Java 類里的靜態字段或方法. 被壓入到 ValueStack 棧的對象上的公共字段和方法
>默認情況下, Struts2 不允許調用任意 Java 類靜態方法, 需要重新設置 struts.ognl.allowStaticMethodAccess 標記變量的值為 true.
>調用靜態字段或方法需要使用如下所示的語法:
-- @fullyQualifiedClassName@fieldName:
@java.util.Calendar@DECEMBER
- -@fullyQualifiedClassName@methodName(argumentList):
@app4.Util@now()
>調用一個實例字段或方法的語法, 其中 object 是 Object Stack 棧里的某個對象的引用:
-- .object.fieldName: [0].datePattern
-- .object.methodName(argumentList): [0].repeat(3, “Hello”);
例子:
1 <!-- 使用ognl,調用public 類的public類型的靜態字段和靜態方法 -->
2 <s:property value="@java.lang.Math@PI"/>
3 <br><br>
4 <s:property value="@java.lang.Math@cos(0)"/>
5 <br><br>
6
7 <!-- 調用對象棧的方法為一個屬性賦值 -->
8 <s:property value="setProductName('jason') "/>
9 <br><br>
10 <s:property value="productName"/>
>調用數組對象的屬性
1 <!-- 調用數組對象的屬性 -->
2 <% 3 String[] names = new String[] {"aa","bb","cc"}; 4 request.setAttribute("names", names); 5 %>
6 <br><br>
7 length:<s:property value="#attr.names.length"/>
8 <br><br>
9 names[2]:<s:property value="#attr.names[2]"/>
>訪問 List 類型的屬性
有些屬性將返回的類型是 java.util.List, 可以像讀取任何其他屬性那樣讀取它們. 這種 List 的各個元素是字符串, 以逗號分隔, 並且帶方括號
可以使用下標訪問 List 中指定的元素: colors[0]
可以通過調用其 size 方法或專用關鍵字 size 的方法查出給定List 的長度: colors.size 或 colors.size()
可以通過使用 isEmpty() 方法或專用關鍵字 isEmpty 來得知給定的 List 是不是空. colors.isEmpty 或 colors.isEmpty()
還可以使用 OGNL 表達式來創建 List, 創建一個 List 與聲明一個 Java 數組是相同的: {“Red”, “Black”, “Green”}
>訪問 Map 類型的屬性
讀取一個 Map 類型的屬性將以如下所示的格式返回它所有的鍵值對:
若希望檢索出某個 Map 的值, 需要使用如下格式: map[key]
可以使用 size 或 size() 得出某個給定的 Map 的鍵值對的個數
可以使用 isEmpty 或 isEmpty() 檢查某給定 Map 是不是空.
1 <!-- 使用ognl 訪問map 操作 -->
2 <% 3 Map<String, String> letters = new HashMap<String, String>(); 4 letters.put("AA", "a"); 5 letters.put("BB", "b"); 6 letters.put("CC", "c"); 7 request.setAttribute("letters", letters); 8 %> 9 letters.length:<s:property value="#attr.letters.size"/>
10 <br><br>
11 AA:<s:property value="#attr.letters['AA']"/>
使用 EL 訪問值棧中對象的屬性
<s:property value=“fieldName”> 也可以通過 JSP EL 來達到目的: ${fieldName}
原理: Struts2 將包裝 HttpServletRequest 對象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper 對象傳到頁面上, 而這個類重寫了 getAttribute() 方法.