国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Struts2 ActionContext 中的數據詳解

Struts2 ActionContext 中的數據詳解

2020-05-29 14:42Java教程網 JAVA教程

這篇文章主要介紹了Struts2 ActionContext 中的數據詳解,需要的朋友可以參考下

ActionContext

    ActionContext是Action的上下文,Struts2自動在其中保存了一些在Action執行過程中所需的對象,比如session, parameters, locale等。Struts2會根據每個執行HTTP請求的線程來創建對應的ActionContext,即一個線程有一個唯一的ActionContext。因此,使用者可以使用靜態方法ActionContext.getContext()來獲取當前線程的ActionContext,也正是由于這個原因,使用者不用去操心讓Action是線程安全的。

    無論如何,ActionContext都是用來存放數據的。Struts2本身會在其中放入不少數據,而使用者也可以放入自己想要的數據。ActionContext本身的數據結構是映射結構,即一個Map,用key來映射value。所以使用者完全可以像使用Map一樣來使用它,或者直接使用Action.getContextMap()方法來對Map進行操作。

    Struts2本身在其中放入的數據有ActionInvocation、application(即ServletContext)、conversionErrors、Locale、action的name、request的參數、HTTP的Session以及值棧等。完整的列表請參考它的Javadoc(本文附錄有對它包含內容的討論)。

    由于ActionContext的線程唯一和靜態方法就能獲得的特性,使得在非Action類中可以直接獲得它,而不需要等待Action傳入或注入。需要注意的是,它僅在由于request而創建的線程中有效(因為request時才創建對應的ActionContext),而在服務器啟動的線程中(比如fliter的init方法)無效。由于在非Action類中訪問其的方便性,ActionContext也可以用來在非Action類中向JSP傳遞數據(因為JSP也能很方便的訪問它)。

   ValueStack與ActionContext的聯系和區別:

相同點:它們都是在一次HTTP請求的范圍內使用的,即它們的生命周期都是一次請求。
不同點:值棧是棧的結構,ActionContext是映射(Map)的結構。
聯系:ValueStack.getContext()方法得到的Map其實就是ActionContext的Map。查看Struts2的源代碼可知(Struts2.3.1.2的org.apache.struts2.dispatcher.ng.PrepareOperations的第79行,createActionContext方法),在創建ActionContext時,就是把ValueStack.getContext()作為ActionContext的構造函數的參數。所以,ValueStack和ActionContext本質上可以互相獲得。
注意:在一些文檔中,會出現把對象存入“stack's context”的字樣,其實就是把值存入了ActionContext。所以在閱讀這些文檔時,要看清楚,到底是放入了棧結構(即值棧),還是映射結構(值棧的context,即ActionContext)。

如何獲得ActionContext:

在自定義的攔截器中:使用ActionInvocation.getInvocationContext()或者使用ActionContext.getContext()。
在Action類中:讓攔截器注入或者使用ActionContext.getContext()。
在非Action類中:讓Action類傳遞參數、使用注入機制注入或者使用ActionContext.getContext()。注意:只有運行在request線程中的代碼才能調用ActionContext.getContext(),否則返回的是null。
在JSP中:一般不需要獲得ActionContext本身。

    如何向ActionContext中存入值:

在攔截器、Action類、非Action類等Java類中:使用ActionContext.put(Object key, Object value)方法。
在JSP中:標簽<s:set value="..."/>默認將值存入ActionContext中(當然,<s:set>標簽還可以把值存到其他地方)。另外,許多標簽都有var屬性(以前用的是id屬性,現在id屬性已被棄用),這個屬性能向ActionContext存入值,key為var屬性的值,value為標簽的value屬性的值。(有些文檔寫的是向ValueStack的context存入值,其實是一樣的)

    如何從ActionContext中讀取值:

在攔截器、Action類、非Action類等Java類中:使用ActionContext.get(Object key)方法。
在JSP中:使用#開頭的Ognl表達式,比如<s:property value="#name"/>會調用ActionContext.get("name")方法。注意:如果某標簽的屬性默認不作為Ognl表達式解析,則需要使用%{}把表達式括起來,于是就會出現類似“%{#name}的表達式”。(“#”的更多用途參見這里)

    總之,在JSP中使用ActionContext一方面是由于它是映射結構,另一方面是能讀取Action的一些配置。當你需要為許多Action提供通用的值的話,可以讓每個Action都提供getXXX()方法,但更好的方法是在攔截器或JSP模板中把這些通用的值存放到ActionContext中(因為攔截器或JSP模板往往通用于多個Action)。
 
    一些例子:

Java代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 本類將演示攔截器中對ActionContext的操作 
publicclass MyInterceptor extends AbstractInterceptor { 
 
  public String intercept(ActionInvocation invocation) throws Exception { 
    // 獲得ActionContext 
    ActionContext actionContext = invocation.getInvocationContext(); 
    // 存入值 
    Person person = new Person(); 
    actionContext.put("person", person); 
    // 獲取值 
    Object value = actionContext.get("person"); 
    // 獲取HttpServletRequest 
    HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST); 
    // 獲取request的Map,即HttpServletRequest.getAttribute(...)和HttpServletRequest.setAttribute(...)所操作的值
    Map requestMap = (Map) actionContext.get("request"); 
    // 其他代碼 
    // ...... 
    return invocation.invoke(); 
  
}

Java代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 本類將演示在Action中對ActionContext進行操作 
publicclass MyAction extends ActionSupport { 
 
  @Override
  public String execute() throws Exception { 
    // 獲得值棧 
    ActionContext actionContext = ActionContext.getContext(); 
    // 存入值 
    Person person = new Person();// 這是之前例子中定義的類
    actionContext.put("person", person); 
    // 獲取值 
    Object object = actionContext.get("person"); 
    // 其他代碼 
    // ...... 
    return SUCCESS; 
  
}

Html代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html>
  <head>
    <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
    <title>JSP Page</title>
  </head>
  <body>
    <!-- 本JSP將演示在JSP中對ActionContext的使用 -->
    <!-- 本JSP為MyAction對應的JSP -->
 
    <!-- 由于Action中已經向ActionContext存入了key為"person"的值,所以可以使用“#person”來獲取它,如下 -->
    <s:propertyvalue="#person"/>
    <!-- 獲得person的name屬性,如下 -->
    <s:propertyvalue="#person.name"/>
    <!-- 獲得Struts2在ActionContext中存入的值,比如request的Map,如下 -->
    <s:propertyvalue="#request"/>
    <!-- 獲得Struts2在ActionContext中存入的值,比如session的Map,如下 -->
    <s:propertyvalue="#session"/>
    <!-- 獲得Struts2在ActionContext中存入的值,request請求傳遞的GET參數或POST參數的Map,如下 -->
    <s:propertyvalue="#parameters"/>
      
    <!-- 以下演示在JSP中把值存入ActionContext中 -->
    <!-- 存入一個字符串"myName",key為"myKey",如下 -->
    <s:setvalue="%{'myName'}"var="myKey"/>
    <!-- 使用s:bean標簽來創建一個對象,并把它存入ActionContext中,key為myObject,如下 -->
    <s:beanname="com.example.Person"var="myObject"/>
    <!-- 之后就可以用“#”來讀取它們,如下 -->
    <s:propertyvalue="#myKey"/>
    <s:propertyvalue="#myObject"/>
  </body>
</html>

3. HttpServletRequest類或request的Map
    Struts2中提供了兩種對request的操作:一種是Web服務器提供的HttpServletRequest類,這和傳統Java Web項目中的操作request的方式相同;另一種是一個“request的Map”,即封裝了HttpServletRequest的attributes的映射類,操作該Map相當于操作HttpServletRequest的attributes。之所以提供了Map的操作方式,一是方便操作,二是能方便使用Ognl在JSP標簽中讀取request。無論如何,這兩個request是互通的。至于request的生命周期等概念,與其他的Java Web項目沒有區別,本文不再詳述。

使用HttpServletRequest類還是request的Map

雖然兩者是互通的,但就讀取request的attributes而言,使用request的Map要方便許多,并且不會暴露不必要的接口。當然,HttpServletRequest有一些request的Map沒有的方法,使用這些方法時當然還是要用前者。

使用request的Map還是ActionContext:

兩者都是Map,兩者的生命周期都是一個請求。
傳統的Java Web項目中,往往是通過request的attributes來向JSP傳遞值的:先在Servlet里setAttribute(),然后在JSP里getAttribute()。當然在Struts2的項目中,你仍然可以使用這個方法,然而拋棄了Struts2提供的傳遞功能是得不償失的。雖然筆者沒有找到官方文檔說一定要用ActionContext替換request的Map,也沒有發現程序中有能獲得ActionContext卻獲得不了request的Map的地方,但在Struts2框架下,操作ActionContext要比操作request的Map更加方便。因此,筆者建議:盡量使用ActionContext而不是request的Map來傳遞值。
request的Map有時候會包含其他框架設置的值,比如Spring框架。獲取這些值的時候就需要用request的Map了,因為ActionContext里沒有。
通過ActionContext可以獲得HttpServletRequest類:“HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);”。
通過ActionContext也可以獲得request的Map:“Map requestMap = (Map) actionContext.get("request");”。因此,在JSP標簽中,使用表達式“#request”就可以獲得request的Map的數據。

如何獲得HttpServletRequest:

如果已經有ActionContext,則使用“actionContext.get(StrutsStatics.HTTP_REQUEST)”來獲得HttpServletRequest。
在自定義的攔截器中,先獲得ActionContext,再通過ActionContext來獲得。
在Action中,先獲得ActionContext,再通過ActionContext來獲得。或者讓Action實現ServletRequestAware接口,并使用ServletConfigInterceptor攔截器,這樣這個攔截器就會注入HttpServletRequest。
在JSP中,一般不需要獲得HttpServletRequest。

如何獲得request的Map:

如果已經有ActionContext,則使用“actionContext.get("request")”來獲得。
在自定義的攔截器中,先獲得 ActionContext,再通過ActionContext來獲得。
在Action中,先獲得ActionContext,再通過ActionContext來獲得。或者讓Action實現RequestAware接口,并使用ServletConfigInterceptor攔截器,這樣這個攔截器就會注入Map request。
在JSP中,用“#request”來獲得request的Map,用“#request.key”或者“#request['key']”來讀取Map中的值。

總之,request仍然符合Java Web網站的一般規律。不過筆者建議使用者應盡量避免用request傳值。

一些例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 本類將演示攔截器中對HttpServletRequest和request的Map的操作 
publicclass MyInterceptor extends AbstractInterceptor { 
 
  public String intercept(ActionInvocation invocation) throws Exception { 
    // 獲得ActionContext 
    ActionContext actionContext = invocation.getInvocationContext(); 
    // 獲得HttpServletRequest 
    HttpServletRequest httpServletRequest=(HttpServletRequest)actionContext.get(StrutsStatics.HTTP_REQUEST); 
    // 獲得request的Map 
    Map requestMap = (Map) actionContext.get("request"); 
    // 創建一個類作為實例 
    Person person = new Person(); 
    // 以下兩行的語句作用相同 
    httpServletRequest.setAttribute("person", person); 
    requestMap.put("person", person); 
    // 其他代碼 
    // ...... 
    return invocation.invoke(); 
  
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 本類將演示在Action中對HttpServletRequest和request的Map進行操作(靜態方法獲得ActionContext)
publicclass MyAction extends ActionSupport { 
 
  @Override
  public String execute() throws Exception { 
    // 獲得ActionContext 
    ActionContext actionContext = ActionContext.getContext(); 
    // 獲得HttpServletRequest 
    HttpServletRequest httpServletRequest=(HttpServletRequest)actionContext.get(StrutsStatics.HTTP_REQUEST); 
    // 獲得request的Map 
    Map requestMap = (Map) actionContext.get("request"); 
    // 創建一個類作為實例 
    Person person = new Person(); 
    // 以下兩行的語句作用相同 
    httpServletRequest.setAttribute("person", person); 
    requestMap.put("person", person); 
    // 其他代碼 
    // ...... 
    return SUCCESS; 
  
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 本類將演示在Action中使用ServletRequestAware獲得HttpServletRequest(注意:要使用ServletConfigInterceptor攔截器)
publicclass MyAction extends ActionSupport implements ServletRequestAware { 
 
  private HttpServletRequest request; 
    
  //此方法是接口ServletRequestAware的方法 
  publicvoid setServletRequest(HttpServletRequest request) { 
    this.request = request; 
  
 
  @Override
  public String execute() throws Exception { 
    // HttpServletRequest已在該類的字段中準備好,可直接使用
    // ...... 
    return SUCCESS; 
  
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 本類將演示在Action中使用ServletRequestAware獲得request的Map(注意:要使用ServletConfigInterceptor攔截器)
publicclass MyAction extends ActionSupport implements RequestAware { 
 
  Map<String, Object> request; 
 
  // 該方法是接口RequestAware的方法 
  publicvoid setRequest(Map<String, Object> request) { 
    this.request = request; 
  
 
  @Override
  public String execute() throws Exception { 
    // request的Map已在該類的字段中準備好,可直接使用 
    // ...... 
    return SUCCESS; 
  
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html> 
<html> 
  <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
    <title>JSP Page</title> 
  </head> 
  <body> 
    <!-- 本JSP將演示在JSP中對request的Map的使用 --> 
    <!-- 本JSP為MyAction對應的JSP --> 
 
    <!-- request的Map是Struts2自動在ActionContext中存入的值(key為request),所以使用“#”來訪問ActionContext,從中讀取request --> 
    <s:property value="#request"/> 
    <!-- 以下兩行均是訪問request的Map中key為“name”的值 --> 
    <s:property value="#request.name"/> 
    <s:property value="#request['name']"/> 
  </body> 
</html>

3. Parameters,即GET請求或POST請求的參數

Parameters為GET或POST等請求時瀏覽器向服務器傳遞而來的參數。在傳統的Java Web項目中,使用HttpServletRequest.getParameter()等方法來獲取參數,并且可以直接使用HttpServletRequest.getParameterMap()來獲得一個封裝了參數的Map。而在Struts2中,Struts2直接把上述Map存放到了ActionContext中,key為“parameters”。另外,ActionContext還直接提供了ActionContext.getParameters()方法來獲得這個Map。因此,在Struts2的各個部件中操作parameters的方法和操作request的Map的方法十分相似,本段不再詳述。

4. HttpServletSession類和session的Map

傳統Java Web項目中的session是我們都熟悉的,我們用它來記錄一個用戶的會話狀態。Struts2把HttpServletSession封裝到了一個Map中,即“session的Map”,這類似對request的處理。然而為了節省系統資源,我們在不需要session的時候不會創建session。可能正是因為這個緣故,Struts2中沒有把HttpServletSession放入ActionContext中,如果你的程序需要使用HttpServletSession,應該先獲得HttpServletRequest,然后使用getSession()或getSession(boolean b)來獲得它,同時決定是否需要創建session。對于session的Map,Struts2仍然把它放入了ActionContext中(key為"session"),但是不要擔心,這個Map的機制使得只有put新值時才會創建session。總之,Struts2中對HttpServletSession的操作要先通過HttpServletRequest來獲得它,而對session的Map的操作與對request的Map的操作如出一轍,本段不再詳述。

5. ServletContext和application的Map

傳統的Java Web項目中,ServletContext用來存放全局變量,每個Java虛擬機每個Web項目只有一個ServletContext。這個ServletContext是由Web服務器創建的,來保證它的唯一性。ServletContext有一些方法能操作它的attributes,這些操作方法和操作一個Map類似。于是,Struts2又來封裝了:它把ServletContext的attributes封裝到了一個Map中,即“application的Map”,并且也放入的ActionContext中(key為application),因此,對application的Map的操作就如果對request的Map操作,本段不再詳述。
至于對ServletContext的操作,與HttpServletRequest的操作類似:Struts2將ServletContext放到了 ActionContext中,并且ServletConfigInterceptor提供了對ServletContext的注入接口ServletContextAware。因此,本段不再詳述。
注意:在Ognl表達式中使用“#application”可以得到application的Map,而不是ServletContext。然而在JSP嵌入的Java代碼中(比如“<% application.getAttribute(""); %>”),application為ServletContext,而不是Map。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成av在线| 免费观看的av | 亚洲免费a | 成人在线免费观看小视频 | 色综合一区二区 | 国产久| 亚洲激情在线播放 | 国产精品日本欧美一区二区三区 | 成人在线网址 | 亚洲精品高潮呻吟久久av | 久久久久国产精品免费免费搜索 | 高清成人 | 亚洲欧美中文日韩在线v日本 | 国产尤物 | 精品国产一区二区国模嫣然 | 黄色一级毛片免费看 | 丰满白嫩老熟女毛片 | 色8久久| 日韩一区二区三区在线 | 日韩国产精品一区 | 亚洲欧美日韩系列 | 国产精品亚洲第一区在线暖暖韩国 | 久久精品国产一区二区三 | 第一色网站 | 精品久久久久久久久久久 | 日韩视频精品在线 | 综合久久久久 | 观看av| a在线观看 | 视频在线一区二区三区 | 免费观看特级毛片 | 欧美女人性 | 国产一区在线视频观看 | 亚洲国产一区二区三区精品 | 精品久久久久久久久久久久 | 日本a视频 | 国产高清免费 | a毛片| 亚洲午夜激情 | 欧美麻豆视频 | 国产高清在线 |