struts2 ognl

值棧是靜態注入生成的,值棧有對象棧和map棧。




從圖可以看出,map棧分爲兩部分,圖中map棧左邊部分跟對象棧的內存結構一樣。可以根據ActionContext.getContext().getValueStack().getRoot()訪問對象棧,還可以通過ActionContext.getContext().getValueStack().getContext()訪問。

值棧的生命週期:值棧的生命週期就是一次請求

值棧的數據結構:對象棧和map棧

對象棧和map棧的區別:對象棧是一個list,map棧是一個map

怎麼樣把數據放到map棧中:這個方法ActionContext.getContext().put("departmentList", departmentList);可以把departmentList放到map棧中。這個方法ServletActionContext.getRequest().setAttribute("departmentList", departmentList);把departmentList放到request中,在頁面中通過#request.departmentList返回,這裏要迭代list集合.



怎麼樣把數據放到對象棧中:例如ActionContext.getContext().getValueStack().push(departmentList);ActionContext.getContext().getValueStack().getRoot().add(0,departmentList);這兩個方法可以把departmentList放到對象棧棧頂;ActionContext.getContext().getValueStack().getRoot().add(departmentList);這個方法可以把departmentList放到對象棧棧底;ActionContext.getContext().getValueStack().peek();這個方法獲取對象棧的棧頂元素;ActionContext.getContext().getValueStack().pop();這個方法移除對象棧的棧頂元素,也可以通過ActionContext.getContext().getValueStack().getRoot().remove(0);移除對象棧的棧頂元素


對象棧中的數據有什麼特殊之處:

*****對象棧的說明:1.處於對象棧中的對象,它的屬性是可以直接訪問的。2.如果在對象棧中有相同名稱的屬性,那麼從棧頂開始查找,直到找到爲止。3.一般情況下回顯的數據應該放在對象棧中,這樣效率比較高。4.用Ognl表達式訪問對象棧,直接屬性名稱就可以了,不用加#。

*****map棧的說明:1.request,session,application都在map棧中。2.可以把一個對象放到map中。3.Ognl表達式訪問map棧中的內容:如果一個對象在map中,那麼就是#request.對象的key值.屬性; 如果一個對象直接放入到map中,那麼就是#對象的key值.屬性。注意:把一個對象放到map棧中,你是不能直接訪問這個對象的屬性的。

把一個map放到對象棧的棧頂:ActionContext.getContext().getValueStack().set(key,o);

以上轉載於:https://www.jianshu.com/p/320e1d31576f

最後再來談一下關於ActionContext.getContext().getValueStack().setValue(key,o)方法。此方法有一個巨坑:

a. 當對象棧的頂部是一個Action時,那麼該方法就會去查找匹配Action是否有key的set***方法。如果沒有則在debug模式下就會拋出異常。

	      ValueStack vs= (ValueStack)request.getAttribute("struts.valueStack");
	     /* vs.set("vsSet", "haha");
	      vs.set("userMap", user);
	      vs.set("vsSet1", "haha1");*/
	      /*vs.set("vsSet1", "haha1");*/
	      vs.setValue("vsSetValue", "<haha>");
	      

異常信息:
Error setting expression 'vsSetValue' with value '<haha>'
異常堆棧:

Error setting expression 'vsSetValue' with value '<haha>' - [unknown location]at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:202)at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:179)

b.當對象棧的頂部不是一個Action時而是一個Map時該值植入到map,而非action,即使action中有該sett**方法。典型用法:

	      ValueStack vs= (ValueStack)request.getAttribute("struts.valueStack");
	     /* vs.set("vsSet", "haha");
	      vs.set("userMap", user);
	      vs.set("vsSet1", "haha1");*/
	      vs.set("vsSet1", "haha1");
	      vs.setValue("vsSetValue", "<haha>");

此時對象棧的頂部不是action,而是一個Map對象,key鍵爲vsSetValue的鍵值對將會放入棧頂的Map中,action中將不會獲得賦值。

ActionContext.getContext().getValueStack().push(o);

ValueStack vs= (ValueStack)request.getAttribute("struts.valueStack");
vs.push("vsSetValue");
vs.push("vsSetValue2");

1)push() 方法設置值,沒有名稱,只有設置的值

2)push() 方法會把向值棧中放的數據存到 top 數組中。最後一個放入的在最頂部,以此類推。

3)JSP頁面用struts標籤取值寫法

<s:property value="[0].top"/><br>
<s:property value="[1].top"/><br>

 ActionContext.getContext().put(key, value);

ActionContext.getContext().put()就是把屬性放到了action的上下文中。ActionContext本身就是一個MAP,你放入的是一個鍵值對。頁面中取值:

${requestScope.greeting} 或者 <%=request.getAttribute("greeting")%> 

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