前一段時間,有關chain的機制着實困繞了許久.儘管網上有許多關於chain的解說,但要不是隻談大理論,不結合實例;要不就是隻有示例,沒有挖出示例背後的意義.
先解釋下chain吧:
Chain:基本用途是構造成一條動作鏈。前一個動作將控制權轉交給後一個動作,而前一個動作的狀態在後一個動作裏仍然保持着。動作鏈由Chaining攔截器負責處理,因爲這個攔截器是defaultStack攔截器棧的一份子,多以你隨時都可以使用動作鏈。
有人說:chain是共享valuestack;也有人說chain是共享表單參數.就我個人而言,以上兩種說法都不見完全正確.
先看一個chain的例子:
struts.xml:
<package name="default" extends="struts-default">
<action name="action1" class="web.action.Action1">
<result type="chain">action2</result>
</action>
<action name="action2" class="web.action.Action2">
<interceptor-ref name="defaultStack"></interceptor-ref>
<result>/result2.jsp</result>
</action>
</package>
Action1.java
public class Action1 extends ActionSupport {
private String str1;
private String str2;
public String execute() throws Exception {
return SUCCESS;
}
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
}
Action2.java
public class Action2 extends ActionSupport {
private String str1;
private String str2;
public String execute() throws Exception {
return SUCCESS;
}
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
}
接着再上jsp文件:
result1.jsp
<form action="action1.action" method="post">
str1:<input type="text" name="str1"><br/>
str2:<input type="text" name="str2"><br/>
<input type="submit">
</form>
result2.jsp
<s:debug/>
str1:${str1 }
<br/>
str2:${str2 }
其實整個流程如下圖所示:
運行結果也很簡單,沒有懸念:
在result1.jsp輸入:str1=111,str2=222
在result2.jsp顯示:str1=111,str2=222
下面進入探討階段:
首先修改下action1.java,在action1中,修改valuestack中的str1的,如下所示:
public class Action1 extends ActionSupport {
private String str1;
private String str2;
public String execute() throws Exception {
str1="set in action1";
return SUCCESS;
}
//省掉get,set
}
再次來運行.
在result1.jsp輸入:str1=111,str2=222
在result2.jsp顯示:str1=111,str2=222
結果很奇怪?爲什麼在result2.jsp不是顯示str1=set in action1? 難道action1.java中修改過後的str1的值沒有寫入valuestack
那我們看看result2.jsp中通過<s:debug/>打印出來的信息.
從debug信息可以看出:
1)在action1的valuestack中,str1的確被成功修改了.
2)但是action2中的valuestack中,str1還是停留在頁面上輸入的str1的值
難道action1中的valuestack沒有共享到action2中的valuestack?
爲了進一步瞭解事實真相,我們繼續來做實驗:
接下來,我在action2.java中的setStr1(String str)中設置斷點,跟蹤action2中str1的賦值情況
發現:str1其實是被賦了兩次值:第一次是"set in action1",而第二次是"111"
如此就得到了如上所示的運行結果.
很奇怪是吧?
我猜測第二次賦值中的"111"來自jsp提交過後產生的表單參數對象,即parameters.
爲了驗證猜測,我們把result1.jsp中的str1的輸入去掉,如下代碼所示:
<form action="action1.action" method="post">
str2:<input type="text" name="str2"><br/>
<input type="submit">
</form>
然後重新運行result1.jsp
運行過程所下:
在result1.jsp中輸入str2=222
在result2.jsp中顯示:str1=set in action1,str2=222
OK,如此,我們在action1中的對str1的修改成功傳遞給了action2,而action2中setStr1()也只執行了一次.
真相呼之欲出了,我們還是用一幅圖來表示整個過程
如此,在執行第四步的時候,如果表單參數中和action1的valuestack中同時有str1這一項,
則表單參數中str1會覆蓋action1的valuestack中的str1,最終action2的str1是以表單參數中的str1爲準
好了,以上僅是根據運行結果作出的猜測和解釋.
若想進一步瞭解事實的真相,從源代碼的角度解釋這一現象,可參考我接下來要寫的<<淺談struts2之chain[2]>>
先吃飯.下午接着寫<<淺談struts2之chain[2]>>