把數據共享在某一個作用域對象中.
Servlet:
request.setAttribute(String name,Object value);
JSP:
通過EL來獲取.
${name}
------------------------------------
1,通過HttpServletRequest對象傳遞;頁面上使用EL表達式獲取;
優點:易於理解;
缺點:過於依賴Servlet函數;操作複雜,頁面如果有大量數據,非常麻煩;頁面取數據麻煩;
在Strtus2中:引出OGNL和ValueStack.
把數據共享在某一個作用域對象中.
Action:
ActionContext.getContext().put(String name,Object value);
ActionContext.getContext().getSession().put(String name,Object value);
JSP:
此時得依賴Struts2的標籤:
<%@ taglib uri="/struts-tags" prefix="s" %>
再通過<s:property value=”OGNL的語法”>標籤來獲取數據.
1.什麼是OGNL
OGNL是Object Graphic Navigation Language(對象圖導航語言[負責:對象和頁面之間數據傳輸])的縮寫,它是一個開源項目。
Struts2框架使用OGNL作爲默認的表達式語言。
EL(表達式語言),OGNL就是EL的升級版.
作用:Action和視圖(JSP)之間數據交互的橋樑.
講解OGNL之前,先得學習ValueStack.
--------------------------------------------------------------
2.什麼是ValueStack(值棧)
值棧是對應每一個請求對象的輕量級的內存數據中心。
每一次請求的時候,都會創建一個新的ValueStack對象,該ValueStack對象封裝了這一次請求相關的數據信息.
1).ValueStack實際是一個接口,在Struts2中利用OGNL時,實際上使用的是實現了該接口的OgnlValueStack類,這個類是Struts2利用OGNL的基礎。
2).ValueStack貫穿整個Action的生命週期(一次請求):每個Action類的實例都擁有一個ValueStack對象。 ValueStack相當於數據的中轉站,在其中保存 該次請求和當前Action對象和其他相關對象信息。
一次請求,--->一個新的Action對象,---->一個新的ValueStack對象.
3).Struts2框架把ValueStack對象保存在名爲“struts.valueStack”的request屬性中。
底層操作,當存在一次新的請求:
ValueStack vs = new ....;
request.setAttribute("struts.valueStack",vs);
3,如何獲取ValueStack.
方式1: 因爲ValueStack在請求中,屬性名爲:struts.valueStack.
ValueStack vs = request.getAttribute("struts.valueStack");
ValueStack vs = ServletActionContext.getRequest().getAttribute("struts.valueStack");
ValueStack vs = ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
方式2: 通過ActionContext對象獲取
ValueStack vs = ActionContext.getContext().getValueStack();
以上兩種方式獲取的是同一個ValueStack對象.
4.ValueStack內部結構
ValueStack對象中有兩個很重要的屬性,這兩個屬性就是ValueStack的主要內部結構:
------------------------------------
root: 類型: CompoundRoot extends ArrayList : 表示了棧的數據結構(後進先出,後進棧的數據在棧頂)
context: 類型: Map: : 上下文
root:主要存儲Action對象相關的數據信息.
context:主要存儲映射關係數據(key-value).
context存在用root對象的引用(只要拿到context對象就可以獲取到root對象):
context中還存在request、session、application、attr、parameters對象的引用。
獲取到context,就可以獲取ValueStack中所有的數據.
從root中獲取數據: 直接使用屬性名獲取. ---><s:property value="屬性名/位置"/>
從context中獲取數據: #key ---><s:property value="#key"/>
把數據放入ValueStack中的root區域.
1).把數據放入root中:(棧,ArrayList.每次都要壓在棧頂)
方式1:ValueStack對象.getRoot().add(0, Obejct val);//把數據壓入棧頂
方式2:ValueStack對象.getRoot().push(Object val):等價於valueStack對象.getRoot().add(0, Obejct val);
方式3:ValueStack對象.set(String propertyName,Object value);
方式4.在Action中提供一個可訪問的屬性(getter方法).
使用方式4的目的,保證Action在棧頂,如果Action在棧頂,我們可以輕鬆獲取棧頂對象中的數據.
一般的,如果是多條數據(集合),我們不建議存儲在root區域,建議存儲在context區域.
<s:property value="xyz"/><br/> 直接獲取棧頂對象中的xyz屬性值.
<s:property value="[0].top.xyz"/><br/>
---------------------------------------
JSP從ValueStack中root區域取出數據:
此時必須使用Struts的標籤.--->先引入Struts2標籤
<%@ taglib uri="/struts-tags" prefix="s"%>
Struts2的調試標籤:<s:debug/> :主要用來觀察數據在哪一個空間(root,context).
訪問方式:<s:property value="OGNL表達式"/>
1).獲取root中數據:
若:放入root中的數據,沒有屬性名:<s:property value="[0].top"/>,不推薦.
若:放入root中的數據有屬性名: <s:property value="屬性名"/>:直接獲取棧頂對象中的屬性值.
把數據放入ValueStack中的context區域.
2).把數據放入context中:
方式1:ValueStack對象.getContext().put(String key,Object value); 太長了.
方式2:ActionContext對象.put(String key,Object value);
一般的:把集合中的數據放入context中.
---------------------------------------
JSP從ValueStack中context區域取出數據:
2).把context中數據:
<s:property value="#key"/>
主要三點:1:把數據放入root區域
有四個方法,主要用第四個在.在action箇中提供可供訪問的Getter屬性
2:怎麼從root區域取出數據
3:怎麼從把數據存到context區域
3:怎麼從context區域取出數據
5:怎麼獲得valueStack對象