浅谈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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章