Struts2在OGNL之上提供的最大附加特性就是支持值棧(ValueStack),在OGNL上下文中只能有一個根對象,Struts2的值棧則允許存在許多虛擬對象。
一:值棧(ValueStack)
我們可以先獲得ValueStack接口對象
// 01.獲取到ValueStack接口對象 ,在request請求中。 HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack");
打上斷點進行調試
下面我們使用Action類分別向Value Stack和Stack Context放值:
//放到單列Value Stack User user = new User(); user.setAge(12); user.setUsername("陳坤"); vs.getRoot().add(user); //放到雙列Stack Context(取值得加#) vs.getContext().put("user", user);
我們訪問頁面:
<h1>取單列Value Stack</h1> 姓名:<s:property value="username"/><br/> <hr/> <h1>取雙列Stack Context(取值得加#)</h1> 姓名:<s:property value="#user.username"/><br/> <hr/>
結果:
我們知道OGNL中有一個標簽
<s:debug></s:debug>
我們使用來監視Value Stack和Stack Context中的值變化
明顯,我們在Value Stack中找到我們剛剛加入的值
同樣,我們在Stack Context中也找到我們剛剛加入的值(內容太多,只截圖了一部分)
總結:
1.Struts2將OGNL上下文設置為Struts2中的ActionContext(內部使用的仍然是OgnlContext,這點在我們上面調試中的圖可以明顯的看出),並將值棧作為OGNL的根對象。值棧類似於正常的棧,符合後進先出的棧特點,你可以在值棧中放入,刪除和查詢對象,值棧是Struts2的核心。
2.值棧通過一個接口(com.opensymphony.xwork2.util.ValueStack)來定義,對應的實現類是com.opensymphony.xwork2.util.OgnlValueStack。
3.順著值棧,框架在ActionContext中還放置其他對象,包括表示application,session和request的Map對象。這些對象共存於ActionContext中,靠在值棧(OGNL根對象)的旁邊,
可以舉個例子:
4.我們知道,OGNL上下文中的根對象可以直接訪問,不需要使用任何特殊的“標記”,而引用上下文中其他對象則需要使用“#”來標記。由於值棧是上下文中的根對象,因此可以直接訪問。那麼對於值棧中的對象如何訪問呢?Struts2提供了一個特殊的OGNLProperty Accessor,它可以自動查找棧內的所有對象(從棧頂到棧底),直到找到一個具有你所查的屬性的對象。也就是說,對於值棧中的任何對象都可以直接訪問,二不需要使用“#”。