[原創]java WEB學習筆記55:Struts2學習之路---詳解struts2 中 Action,如何訪問web 資源,解耦方式(使用 ActionContext,實現 XxxAware 接口),耦合方式(通過ServletActionContext,通過實現 ServletRequestAware, ServletContextAware 等接口的方式)


本博客的目的:①總結自己的學習過程,相當於學習筆記 ②將自己的經驗分享給大家,相互學習,互相交流,不可商用

內容難免出現問題,歡迎指正,交流,探討,可以留言,也可以通過以下方式聯系。

本人互聯網技術愛好者,互聯網技術發燒友

微博:伊直都在0221

QQ:951226918

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

1.Action 類

  1)action: 應用程序可以完成的每一個操作. 代表一個sturts2 的請求。例如: 顯示一個登陸表單; 把產品信息保存起來

  2)Action類: 普通的 Java 類,能夠處理struts2 請求的java類, 可以有屬性和方法, 同時必須遵守下面這些規則:

    ① 屬性的名字必須遵守與 JavaBeans 屬性名相同的命名規則. 屬性的類型可以是任意類型. 從字符串到非字符串(基本數據庫類型)之間的數據轉換可以自動發生

    ② 必須有一個不帶參的構造器:反射

    ③ 至少有一個供 struts 在執行這個 action 時調用的方法

      ④ 同一個 Action 類可以包含多個 action 方法.

    ⑤ Struts2 會為每一個 HTTP 請求創建一個新的 Action 實例。即,Action 不是單例的,是線程安全的。

 

 

2.在Action中如何訪問web資源

 

1)什么是web 資源

  HttpServletRequest, HttpSession,ServletContext 等原生的Servlet API

2)為什么訪問web 資源?

  B/S 應用的controller 中必然需要訪問web資源:向域對象中讀寫屬性,讀寫 cookie,獲取realPath  ....

3) 如何訪問?

  ① 和servlet API 解耦的方式:只能訪問有限的Servelt API 對象,且只能訪問其有限的方法(讀取請求參數,讀寫域對象的屬性,是session 失效 ... )

    > 使用 ActionContext

    >實現 XxxAware 接口

注:為了避免與 Servlet API 耦合在一起, 方便 Action 做單元測試, Struts2 對 HttpServletRequest, HttpSession 和 ServletContext 進行了封裝, 構造了 3 個 Map 對象來替代這 3 個對象,

  在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext 對應的 Map 對象來保存和讀取數據.

  

  ② 和servlet API 耦合的方式:可以訪問更多的Servlet API對象,且可以調用其原生的方法。

    > 使用 ServletContext

    >  實現ServletXxxAware接口

 

3.1 和servlet API 解耦的方式

  1)通過 ActionContext 訪問 Web 資源:ActionContext 是 Action 執行的上下文對象, 在 ActionContext 中保存了 Action 執行所需要的所有對象, 包括 parameters, request, session, application 等.

    > 獲取 HttpSession 對應的 Map 對象: public Map getSession() , session 對應的Map 實際上是SessionMap 類型的,強轉之后調用其invalidate() 方法,可以使其session 失效

    > 獲取 ServletContext 對應的 Map 對象: public Map getApplication()

    > 獲取請求參數對應的 Map 對象: public Map getParameters()

    > 獲取 HttpServletRequest 對應的 Map 對象: public Object get(Object key):ActionContext 類中沒有提供類似 getRequest() 這樣的方法來獲取 HttpServletRequest 對應的 Map 對象. 要得到 HttpServletRequest 對應的 Map 對象, 可以通過為 get() 方法傳遞 “request” 參數實現

   struts.xml  

 1 <package name="testAction" namespace="/" extends="struts-default">
 2     
 3         <action name="TestActionContext" class="com.jason.struts.action.TestActionContextAction" method="execute">
 4         
 5         <result>/test-actionContext.jsp</result>
 6         
 7         </action>
 8     
 9     </package>
10     

 

 

    

 

TestActionContextAction.java
 1 package com.jason.struts.action;  2 
 3 import java.util.Map;  4 
 5 import com.opensymphony.xwork2.ActionContext;  6 
 7 /**
 8  *  9  * @ClassName:TestActionContextAction 10  * @Description:TODO 11  * @author: jason_zhangz@163.com 12  * @date:2016年8月2日下午6:01:48 13  * 14  * 15  */
16 public class TestActionContextAction { 17     
18     public String execute(){ 19         
20         //0.獲取actionContext對象,是Action 的上下文對象。可以從中獲取到Action獲取所以信息
21         
22         ActionContext actionContext = ActionContext.getContext(); 23         
24         //1.獲取application 對應的Map,並向其中添加一個屬性 25             //通過application 對象的 getApplication() 方法來獲取application 對象的map 對象
26             Map<String, Object> applicationMap = actionContext.getApplication(); 27             //設置屬性
28             applicationMap.put("applicationKey", "applicationValue"); 29             
30         //2.session
31             Map<String, Object> sessionMap = actionContext.getSession(); 32             sessionMap.put("sessionKey", "sessionValue"); 33             
34         
35         //3.request 36         //ActionContext 中並沒有提供 getRequest 方法來獲取 request 對應的 Map,需要手工調用get(),傳入 requet 字符串來獲取 
37             
38             Map<String, Object> requsetMap = (Map<String, Object>) actionContext.get("request"); 39             requsetMap.put("requestKey", "requestValue"); 40         
41         //4.獲取請求參數對應的Map,並且獲取指定的參數值 42         //鍵:請求參數的名字;值:請求參數的值對應的字符串數組 43         //注意:1. getParameters 的返回值為Map<String, Object> ,而不是Map<String ,String[]> 44         // 2.parameters 這個Map 只能讀,不能寫入數據,如果寫入,但不出錯,同時也不起作用
45             Map<String, Object> paramters = actionContext.getParameters(); 46             System.out.println(((String [])paramters.get("name"))[0]); 47             
48             
49             paramters.put("age", 100); 50         return "success"; 51  } 52 
53 }

 

index.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>testAction index page</title>
 8 </head>
 9 <body>
10 
11     <a href="TestActionContext.action?name=jason"> Test ActionContext</a>
12 </body>
13 </html>

 

 

 

test-actionContest.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>test-actionContext  page</title>
 8 </head>
 9 <body>
10 
11     <h4>test-actionContext page</h4>
12     
13  application: ${applicationScope.applicationKey } 14     <br><br>
15     
16     
17  application: ${sessionScope.sessionnKey } 18     <br><br>
19     
20     
21  request:${requestScope.requestKey } 22     <br><br>
23     
24  age:${parameters.age } 25     
26     
27 </body>
28 </html>

 

 

3.2實現 XxxAware 接口

 

 TestAwareAction.java

 1 package com.jason.struts.action;  2 
 3 import java.util.Map;  4 
 5 import org.apache.struts2.interceptor.ApplicationAware;  6 import org.apache.struts2.interceptor.ParameterAware;  7 import org.apache.struts2.interceptor.RequestAware;  8 import org.apache.struts2.interceptor.SessionAware;  9 
10 /**
11  * 12  * @ClassName:TestAwareAction 13  * @Description:測試 解耦 實現 XxxAware 接口 14  * @author: jason_zhangz@163.com 15  * @date:2016年8月5日下午5:28:42 16  * 17  * 18  */
19 public class TestAwareAction  implements ApplicationAware ,SessionAware,RequestAware,ParameterAware{ 20     //通過實現不同的Aware 的接口,之后實現 setXX 方法,而struts2 用注入的方式,將對應的map 對象注入到自己所定義個私有變量中,之后調用execute方法
21     
22     public String execute(){ 23 24 //1.向application 中加入一個屬性:applicationKey - applicationValue 25 application.put("applicationKey2", "applicationValue2"); 26 //2.從application 中讀取一個屬性data,打印 27 System.out.println(application.get("date")); 28 29 return "success"; 30 } 31 
32     private Map<String, Object> application; 33     private Map<String,String[]> parameters; 34     private Map<String, Object> request; 35     private Map<String, Object> session; 36     
37  @Override 38 public void setApplication(Map<String, Object> application) { 39 40 this.application = application; 41 } 42  @Override 43     public void setParameters(Map<String, String[]> parameters) { 44         this.parameters = parameters; 45         
46  } 47  @Override 48     public void setRequest(Map<String, Object> request) { 49         this.request = request; 50         
51  } 52  @Override 53     public void setSession(Map<String, Object> session) { 54         this.session = session; 55         
56  } 57     
58     
59 }

 

 

 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: 包. Struts2 使用package 來組織模塊  9  name屬性:必須. 用於其他的包引用當前包。一般為當前模塊的名字 10  extends:當前包繼承哪個包,繼承的,即可以繼承其中的所有的配置。通常情況下,繼承 struts-default 11  namespace:可選,如果沒有給出,則 以 "/" 為默認值。若namespace有一個非默認值,則要想調用這個包里面的action,則必須把這個屬性所定義的命名空間添加到先關的URI 字符串里。在servletPath 前面添加。 12  例如: http://localhost:8080/contextpath/namespace/servletPath 13          
14          
15      -->
16     <!-- <package name="helloword" extends="struts-default"> 17         
18  配置一個action: 一個struts2 的請求就是一個action 19         
20  name:對應一個Struts2 的請求的名字(或者對應一個servletPath,但是去除 / 和 擴展名),不含擴展名 21  class:的默認值為:com.opensymphony.xwork2.ActionSupport 22  method:的默認值為:execute 23             
24         
25  <action name="product-input" 26  class="com.opensymphony.xwork2.ActionSupport" 27  method="execute"> 28         
29                 
30  result:結果。即,要訪問的路徑。表示action 方法執行后可能返回的一個結果。一個action節點可能有多個result 子節點。多個子節點使用name屬性來區分, 31  name:標示一個一個result,和action 方法的返回值對應。默認值為 success 32  type:表示結果的類型,默認為dispatcher(轉發到 結果) 33         
34  <result name="success" type="dispatcher">/struts2/input.jsp</result> 35  </action> 36         
37         
38  <action name="product-save" class="com.jason.struts.helloword.Product" method="save"> 39  <result name="details">/struts2/details.jsp</result> 40 
41  </action> 42     
43     
44     
45  </package> 46     
47      -->
48     
49      <package name="testAction" namespace="/" extends="struts-default">
50     
51          <action name="TestActionContext" class="com.jason.struts.action.TestActionContextAction" method="execute">
52         
53                 <result>/test-actionContext.jsp</result>
54         
55         </action>
56         
57         
58         <action name="TestAware" class="com.jason.struts.action.TestAwareAction" method="execute">
59         
60                 <result>/test-aware.jsp</result>
61         
62         </action>
63     
64     </package>
65     
66     
67     
68     
69 
70     
71     
72 </struts>

 

 

 test-aware.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>Test Aware Page<</title>
 8 </head>
 9 <body>
10 
11     <h4>Test Aware Page</h4>
12     
13  application:${applicationScope.applicationKey2 } 14 </body>
15 </html>

 

 

index.jsp

 1 <%@page import="java.util.Date"%>
 2 <%@ page language="java" contentType="text/html; charset=UTF-8"
 3  pageEncoding="UTF-8"%>
 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>testAction index page</title>
 9 </head>
10 <body>
11     <%
12         Date date = new Date(); 13  application.setAttribute("date", date); 14     %>
15     <a href="TestActionContext.action"> Test ActionContext</a>
16     <br>
17     <br>
18     <a href="TestAware.action">  TestAware</a>
19 </body>
20 </html>

 

 

 

 

 

 

 

3.3.兩種解耦方式web資源的比較

  1)若一個Action 類中有對個 Action 方法,且多個方法,使用域對象的 Map 或 parameters ,則建議使用實現了Aware 接口的方式。

 

 

3.4. 與Servlet 耦合的訪問方式:需要用到原生的API

方式一:

  1) 直接訪問 Servlet API 將使 Action 與 Servlet 環境耦合在一起,  測試時需要有 Servlet 容器, 不便於對 Action 的單元測試;

  2) 直接獲取 HttpServletRequest 對象: ServletActionContext.getRequest();

    3) 直接獲取 HttpSession 對象:ServletActionContext.getRequest().getSession();

   4) 直接獲取 ServletContext 對象:ServletActionContext.getServletContext();

 

TestServletActionContextAction.java
 1 package com.jason.struts.action;  2 
 3 import javax.servlet.ServletContext;  4 import javax.servlet.http.HttpServletRequest;  5 import javax.servlet.http.HttpSession;  6 
 7 import org.apache.struts2.ServletActionContext;  8 
 9 public class TestServletActionContextAction { 10 
11     
12         public String execute(){ 13             /**
14  * ServletActionContext:可以獲取到當前Action 對象需要的一切的servlet API 相關對象 15  * 常用方法: 16  * 1.獲取 HttpServletRequest :ServletActionContext.getRequest() 17  * 2.獲取 HttpSession :ServletActionContext.getRequest().getSession() 18  * 3.獲取ServletContext:ServletActionContext.getServletContext() 19              */
20             
21             HttpServletRequest request = ServletActionContext.getRequest(); 22             HttpSession session = ServletActionContext.getRequest().getSession(); 23             ServletContext servletContext  = ServletActionContext.getServletContext(); 24             
25             System.out.println("execute ..."); 26             
27             
28             return "success"; 29  } 30 }

 

 

struts.xml

1     
2         <action name="TestServletActionContext" class="com.jason.struts.action.TestServletActionContextAction">
3             <result>/success.jsp</result>
4         </action>

 

 

index.jsp

1 <a href="TestServletActionContext.action">  TestServletActionContext</a>

 

 

方式二:

通過實現 ServletRequestAware, ServletContextAware 等接口的方式

 

TestSerlvetAwareAction.java
 1 package com.jason.struts.action;  2 
 3 import javax.servlet.ServletContext;  4 import javax.servlet.http.HttpServlet;  5 import javax.servlet.http.HttpServletRequest;  6 import javax.servlet.http.HttpServletResponse;  7 
 8 import org.apache.struts2.interceptor.ServletRequestAware;  9 import org.apache.struts2.interceptor.ServletResponseAware; 10 import org.apache.struts2.util.ServletContextAware; 11 
12 
13 /**
14  * 15  * @ClassName:TestSerlvetAwareAction 16  * @Description:通過實現ServletXxxAware 接口的方式可以有Struts2 注入需要的Servlet 相關對象 17  * 18  * ServletRequestAware: 注入HttpServletRequest 對象(常用) 19  * ServletContextAware: 注入 ServletContext 對象(常用) 20  * ServletResponseAware: 21  * 22  * @author: jason_zhangz@163.com 23  * @date:2016年8月18日下午4:35:21 24  * 25  * 26  */
27 public class TestSerlvetAwareAction  implements ServletRequestAware, ServletContextAware,ServletResponseAware{ 28 
29     
30     public String execute(){ 31     
32             System.out.println("execute ..."); 33             
34             return "success"; 35  } 36     
37     private ServletContext servletContext; 38  @Override 39     public void setServletContext(ServletContext context) { 40  System.out.println(context); 41         //org.apache.catalina.core.ApplicationContextFacade@47da4d19
42         this.servletContext = context; 43         
44  } 45     
46     private HttpServletRequest request; 47  @Override 48     public void setServletRequest(HttpServletRequest request) { 49  System.out.println(request); 50         //org.apache.struts2.dispatcher.StrutsRequestWrapper@b8519f4
51         this.request = request; 52         
53  } 54 
55     private HttpServletResponse response; 56  @Override 57     public void setServletResponse(HttpServletResponse response) { 58  System.out.println(response); 59         //org.apache.catalina.connector.ResponseFacade@4f6ae814
60         this.response = response; 61  } 62 
63 }

 

 

Struts.xml

1 <action name="TestServletAwareAction" class="com.jason.struts.action.TestSerlvetAwareAction">
2         
3             <result>/success.jsp</result>
4         </action>

 

 

 index.jsp

1 <a href="TestServletAwareAction.action">  TestServletAwareAction</a>

 

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM