ActionContext.getContext().put(key,value);這個方法是以鍵值對的方式添加進去的
取出來直接根據key取:<%Object value = ActionContext.getContext().get(key)%>取得key對應的value
這個應該是Struts2裡面的内容,那些封裝成Map形式的 如session 、request等對象就是綁定到ActionContext對象上
在一個action中,有一個屬性test,
private String test;
execute方法如下:
public String execute() throws Exception {
test = "vs_test";
ActionContext.getContext().put("test", "actionContext_test");
return "success";
}
在頁面中使用下面兩種方法輸出:
${requestScope.test}
<%= ActionContext.getContext().get("test") %>
如果把execute()方法中
test = "vs_test";
注釋掉;
輸出結果為:
actionContext_test
actionContext_test
action中指派都沒有使用 request.setAttribute()進行指派,
根據資料 ${requestScope.test} 會先通過 request.getAttribute()取值,如果取不到則從 valueStack 中去,
根據第一次的輸出結果,可以看出 test 在 valueStack 中的值為 vs_test,通過 <s:debug/> 也可以看出,
根據第二次的輸出結果,可以看出 ActionContext.getContext().put("test", "actionContext_test") 也是把值放到 valueStack 中了,
但為什麼第一次兩種輸出方式的輸出值不一樣哪?
另外如果我在execute()方法中放入以下代碼:
ActionContext.getContext().getValueStack().set("test", "hello");
${requestScope.test }的 輸出結果變成了 hello,
此時在<s:debug/>中 可以看到作為目前action對象屬性的test ,其值仍為
v 但是沒有我手動放進去的 test,
actionContext.getContext().put()就是把屬性放到action上下文中,這個actionContext本身 就是一個Map,裡面放有預設的Map session等常用屬性,比如可以actionContext.getContext().get(StrutsStatics.HTTP_REQUEST)得到struts2為我們action儲存的HttpServletRequest對象 ,而你Put一個put("test", "actionContext_test"),放的就是一個String對象 。而el表達式能取到action的屬性,是由于struts攔截了request.getAttribute()方法并重新實作了它,如果HttpServletRequest沒有我們要的屬性,就從actionContext中找我們Put的對象 ,再沒有就找valuestack中找,所有你後面把自定義 的test放到值棧中去了,就把本身action中的test屬性蓋了,el就隻能找到這個hello了。
可以參考 下面:
我們知道,JSTL預設是從page,request,session,application這四個Scope逐次查找相應的EL表達式所對應的對象的值。那麼如果要使用JSTL來讀取Action中的變量,就需要把Action中的變量,放到request域中才行。是以,早在 Webwork2.1.X的年代,我們會編寫一個攔截器來做這個事情的。大緻的原理是:在Action執行完傳回之前,依次讀取Action中的所有的變量,并依次調用request.setAttribute()來進行設定。具體的整合方式,請參考以下這篇文檔:http://wiki.opensymphony.com/display/WW/Using+WebWork+and+XWork+with+JSP+2.0+and+JSTL+1.1
不過随着時代的發展,上面的這種方式,已經不再被推薦使用了。(雖然如此,我們依然可以學習它的一個解決問題的思路)目前來說,自從Webwork2.2以後,包括Struts2,都使用另外一種整合方式:對HttpServletRequest進行裝飾。讓我們來看一下源碼:
Java代碼
1. public class StrutsRequestWrapper extends HttpServletRequestWrapper {
2.
3.
7. public StrutsRequestWrapper(HttpServletRequest req) {
8. super(req);
9. }
10.
11.
16. public Object getAttribute(String s) {
17. if (s != null && s.startsWith("javax.servlet")) {
18. // don't bother with the standard javax.servlet attributes, we can short-circuit this
19. // see WW-953 and the forums post linked in that issue for more info
20. return super.getAttribute(s);
21. }
22.
23. ActionContext ctx = ActionContext.getContext();
24. Object attribute = super.getAttribute(s);
25.
26. boolean alreadyIn = false;
27. Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute");
28. if (b != null) {
29. alreadyIn = b.booleanValue();
30. }
31.
32. // note: we don't let # come through or else a request for
33. // #attr.foo or #request.foo could cause an endless loop
34. if (!alreadyIn && attribute == null && s.indexOf("#") == -1) {
35. try {
36. // If not found, then try the ValueStack
37. ctx.put("__requestWrapper.getAttribute", Boolean.TRUE);
38. ValueStack stack = ctx.getValueStack();
39. if (stack != null) {
40. attribute = stack.findValue(s);
41. }
42. } finally {
43. ctx.put("__requestWrapper.getAttribute", Boolean.FALSE);
44. }
45. }
46. return attribute;
47. }
}
ActionContext.getContext().put(key,value);這個方法是以鍵值對的方式添加進去的
取出來直接根據key取:<%Object value = ActionContext.getContext().get(key)%>取得key對應的value
這個應該是Struts2裡面的内容,那些封裝成Map形式的 如session 、request等對象就是綁定到ActionContext對象上