浅谈struts2之chain[1]

简介:         前一段时间,有关chain的机制着实困绕了许久.尽管网上有许多关于chain的解说,但要不是只谈大理论,不结合实例;要不就是只有示例,没有挖出示例背后的意义.     先解释下chain吧:   Chain:基本用途是构造成一条动作链。


        前一段时间,有关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]>>

相关文章
|
Kubernetes 关系型数据库 MySQL
在 K8S Volume 中使用 subPath
在 K8S Volume 中使用 subPath
|
应用服务中间件 nginx 容器
Kubernetes----Pod配置容器端口
Kubernetes----Pod配置容器端口
1435 0
|
测试技术 SDN 数据安全/隐私保护
使用OpenDaylight界面下发流表(上)
使用OpenDaylight界面下发流表(上)
406 0
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
517 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
Java Linux
Linux通配符的使用方法
Linux通配符的使用方法
|
存储 Oracle Linux
在Linux中,支持哪些文件系统类型?
在Linux中,支持哪些文件系统类型?
|
SQL Java 数据库连接
MyBatis 和 Hibernate 有什么区别?
【8月更文挑战第21天】
357 0
带你读《5G 系统技术原理与实现》——1.3.1 SA 组网和NSA 组网
带你读《5G 系统技术原理与实现》——1.3.1 SA 组网和NSA 组网
jmeter connection reset解决方法
方法仅作参考: 1.修改HTTP请求下面的Impementation选项,改成HttpClient4 2.在user.properties文件内修改: hc.parameters.file=hc.parameters #Jmeter 2.10以后禁用了失败请求重试 3.在hc.parameters文件内修改: http.connection.stalecheck$Boolean=true #Jmeter 2.10以后禁用了失效检查 重启Jmeter再尝试一下 注:转载需注明出处及作者。
4126 0
|
Prometheus Kubernetes 监控
Prometheus Operator(上)
Prometheus Operator(上)
554 0