Struts2裡ActionContext的put方法和request的setAttribute方法
在Servlet和jsp的互動中,使用ActionContext.getContext.put(,)方法把值放到了哪裡,使用request.setAttribute(,)把值又放到了哪裡。StackContext和ValueStack,request都有什麼區別。對StackContext,ValueStack,request不是很清楚的小夥伴可以看看~
一、StackContext,ValueStack和request
先看結論吧:
action的例項儲存在ValueStack中。
ActionContext.getContext.put(String,Object)是把物件放到了StackContext中,這個物件跟request,session等一樣,它們平起平坐,但這些都不是根物件,所以要通過#訪問。
request.setAttribute(String,Object)就是把值放到request範圍,而StackConext裡含有request物件,所以可以通過#request.*來訪問。
然後看以下Action的程式碼
public class TestAction extends ActionSupport implements ServletRequestAware{ private String tip; private HttpServletRequest request; public String execute()throws Exception{ setTip("tip來源ValueStack"); ActionContext.getContext().put("tip", "tip來源StackContext"); request.setAttribute("tip", "tip來源Request"); return SUCCESS; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } public String getTip() { return tip; } public void setTip(String tip) { this.tip = tip; } }
分別往ValueStack,StackContext和request這3個範圍裡放入了key一樣,值不一樣的資料。
然後在jsp中訪問3個範圍的tip:
第一行訪問ValueStack裡的tip<body> <s:debug/> <table> <tr> <td>訪問ValueStack</td> <td><s:property value="tip"/></td> </tr> <tr> <td>訪問StackContext</td> <td><s:property value="#tip"/></td> </tr> <tr> <td>訪問Request</td> <td><s:property value="#request.tip"/></td> </tr> </table> </body>
第二行訪問StackContext裡的tip,相當於ActionContext.getContext.get("tip");
第三行訪問request範圍的tip,相當於request.getAttribute("tip");
結果:
訪問ValueStack | tip來源ValueStack |
訪問StackContext | tip來源StackContext |
訪問Request | tip來源Request |
在Debug中也確實可以找到ValueStack,StackContext,request裡分別對應的tip,就是開頭的結論。
ValueStack可以看做StackContext的根物件,那接下來討論一下StackContext和Request。
二、request獲取StackContext裡的值
request通過request.getAttribute()是否可以獲取到StackContext裡的資料呢。
答案是可以。
把剛才action裡的request.setAttribute("tip", "tip來源Request");這句程式碼註釋掉,也就是說不往request範圍放資料。其他程式碼不變
然後執行結果為:
訪問ValueStack | tip來源ValueStack |
訪問StackContext | tip來源StackContext |
訪問Request | tip來源ValueStack |
在request範圍沒有值時,獲取到了ValueStack的資料。那把ValueStack裡的資料也刪除掉看看結果。
註釋掉tip屬性和方法,執行結果為:
訪問ValueStack | tip來源StackContext |
訪問StackContext | tip來源StackContext |
訪問Request | tip來源StackContext |
所以就能看出結果了。
當呼叫request.getAttribute()時,首先會從request範圍的資料裡找,然後從ValueStack裡找,最後到StackContext裡找。
而使用<s:property value="tip"/>時,ValueStack裡沒有,會繼續往StackContext裡找,而不是為null
三、結論
StackContext含有request物件。執行request的getAttribute時,首先會從曾經request範圍的資料裡找,然後從ValueStack裡找,最後到StackContext裡找。最後附上一張Debug裡的截圖。