【9】值棧的概述

1、什麼是值棧

         ValueStack是Struts2的接口,OGNLValueStack是該接口的實現類。ValueStack相當於Struts2數據的中轉站,ValueStack貫穿了整個Action的生命週期,Action是多例的,一次服務器請求就會創建一個Action的實例,同時會爲這個Action創建一個ValueStack對象。Struts2通過OGNL表達式獲取值棧的數據。

2、值棧的內部結構

3、ActionContext與值棧的關係

ActionContext:Action的上下文。通過源碼查看:Struts的核心過濾器執行的過程中,創建ActionContext對象,在創建ActionContext對象的同時創建一個ValueStack,並且將ValueStack存入到ActionContext中。所以通過ActionContext對象,獲得值棧。其實在ValueStack的內部有一個ActionContext的引用。

public class A{

         private B b;

}

 

public class B{

         private A a;

}

ActionContext中有ValueStack的引用,ValueStack中也有ActionContext的引用。

ActionContext之所以能夠訪問ServletAPI其實也是依賴了值棧的。

 

4、如何獲取值棧

  •  通過ActionContext獲取

ValueStack valueStack1 = ActionContext.getContext().getValueStack();

  • 通過request對象獲取-因爲執行Action的過程中,將值棧存入到request域中。

// 獲得reqeust對象獲取

ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest()

        .getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

 

5、如何操作值棧(操作root區域)

  • 直接操作值棧對象

* void set(String name,Object value);

* void push(Object obj);

  •  直接在Action對象提供成員屬性

當Action的實例被創建了,默認的情況下(沒有手動操作值棧,沒有實現模型驅動),Action對象在棧頂的位置。Action中的屬性也會在棧中。提供一個屬性,對該屬性提供一個get方法就可以了。

 

6、獲取值棧的數據

  •  在頁面中使用OGNL表達式進行獲取

<h3>獲取值棧的root區數據</h3>

<s:property value="name"/><br/>

<s:property value="user.username"/>

<s:property value="user.password"/><br/>

<s:property value="username"/>

<s:property value="password"/><br/>

<s:property value="list[0].username"/>

<s:property value="list[0].password"/>

<s:property value="list[1].username"/>

<s:property value="list[1].password"/>

 

<h3>獲取值棧的context區數據</h3>

<s:property value="#request.name"/>

<s:property value="#session.name"/>

<s:property value="#application.name"/>

 

<s:property value="#attr.name"/>

<s:property value="#parameters.id"/>

7、EL如何訪問值棧

    public Object getAttribute(String key) {

        if (key == null) {

            throw new NullPointerException("You must specify a key value");

        }

 

        if (disableRequestAttributeValueStackLookup || key.startsWith("javax.servlet")) {

            // don't bother with the standard javax.servlet attributes, we can short-circuit this

            // see WW-953 and the forums post linked in that issue for more info

            return super.getAttribute(key);

        }

 

ActionContext ctx = ActionContext.getContext();

        Object attribute = super.getAttribute(key);

 

        if (ctx != null && attribute == null) {

            boolean alreadyIn = isTrue((Boolean) ctx.get(REQUEST_WRAPPER_GET_ATTRIBUTE));

 

            // note: we don't let # come through or else a request for

            // #attr.foo or #request.foo could cause an endless loop

            if (!alreadyIn && !key.contains("#")) {

try {

// If not found, then try the ValueStack

ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.TRUE);

ValueStack stack = ctx.getValueStack();

                    if (stack != null) {

attribute = stack.findValue(key);

                    }

finally {

ctx.put(REQUEST_WRAPPER_GET_ATTRIBUTE, Boolean.FALSE);

}

            }

        }

        returnattribute;

    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章