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。