淺談struts2之chain[1]


        前一段時間,有關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]>>

發佈了30 篇原創文章 · 獲贊 34 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章