程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Struts2 ActionContext 中的數據詳解

Struts2 ActionContext 中的數據詳解

編輯:關於JAVA

Struts2 ActionContext 中的數據詳解。本站提示廣大學習愛好者:(Struts2 ActionContext 中的數據詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是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代碼

// 本類將演示攔阻器中對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代碼

// 本類將演示在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代碼

<!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傳值。

一些例子:

// 本類將演示攔阻器中對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();  
  }  
} 
// 本類將演示在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;  
  }  
} 
// 本類將演示在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;  
  }  
} 
// 本類將演示在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;  
  }  
} 
<!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。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved