1. 程式人生 > >Struts2裡ActionContext的put方法和request的setAttribute方法

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:

<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>
第一行訪問ValueStack裡的tip

第二行訪問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裡的截圖。