浅谈struts2之chain

LLM 大模型学习必知必会系列(十一):大模型自动评估理论和实战以及大模型评估框架详解 阅读详情
 前一段时间,有关chain的机制着实困绕了许久.尽管网上有许多关于chain的解说,但要不是只谈大理论,不结合实例;要不就是只有示例,没有挖出示例背后的意义.

    先解释下chain吧:

  Chain:基本用途是构造成一条动作链。前一个动作将控制权转交给后一个动作,而前一个动作的状态在后一个动作里仍然保持着。动作链由Chaining拦截器负责处理,因为这个拦截器是defaultStack拦截器栈的一份子,多以你随时都可以使用动作链。

      有人说:chain是共享valuestack;也有人说chain是共享表单参数.就我个人而言,以上两种说法都不见完全正确.

      先看一个chain的例子:

  struts.xml:

   Action1.java  

    <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>  

    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为准

 

好了,以上仅是根据运行结果作出的猜测和解释.

现在接着写下半部分:从源码的角度谈chain的机制

  因为我的源码全是通过反编译jar包得来,不能保证100%的正确性,若遇到不对的地方,请大家指出.也请大家先谅解

  在<<浅谈struts2之chain[1]>>最后,用了一个简略图来表示chain机制:

  

  但实际上,如果考虑valuestack的话,这幅图应该这样画:

  

  对于此图中,关键性两个步骤:5和6, 实际上涉及到两个拦截器:

  1)chain

       2)params

  也就说,说chain方式的action之间共享valuestack是没有错的,说它们共享parameters也没有错

关键是它们的先后顺序及相互影响      我们来看一下struts-core-2.0.11.jar中struts-default.xml中对这两个拦截器的使用:

  <pre class="html" name="code"><interceptor-stack name="defaultStack">  
            
......省略..........  
  
         <interceptor-ref name="chain"/>  
..................省略...........................  
  
               
        <interceptor-ref name="params">  
                 
 </interceptor-stack>  
</pre><br>  
<pre></pre>  
<p>记注意这两个拦截器的先后顺序:先是chain,然后才是params</p>  
<p>这也就决定了上图中的执行顺序是:先执行5的动作后执行6的动作.</p>  
<p>严格说来,上图中5,6,7,8的动作顺序描述,也不是很严谨,</p>  
<p>真要说完全正确的执行顺序,实际上是先5,7然后再执行6,7,8.</p>  
<p>关于这一点,只需要在调试状态上跟踪下action2中的set方法的调用堆栈就能理解.</p>  
<p> </p>  
<p>好了,接下来我们说说chain和params的定义.还是在struts-default.xml中</p>  
<pre class="html" name="code"> 
 <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>          
  <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>  
</pre>  
<p><br>  
要说chain类型的result,实际上就是构建一条链接,把访问路径上的action对象全放在这个链条上,</p>  
<p>先看下com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ActionInvocation invocation)</p>  
<p>找到关键代码: OgnlUtil.copy(o, invocation.getAction(), ctxMap, excludes, includes);</p>  
<p>这就是把action链条上,上一个action还有上上个action.....总之把action链条上前面访问的所有action对象</p>  
<p>都执行OgnlUtil.copy(.......),也就是把它们的valuestack中的值都赋给当前action的valuestack</p>  
<p><span style="color:#ff6666">举个简单例子,有三个action</span></p>  
<p><span style="color:#ff6666">action1,action2,action3</span></p>  
<p><span style="color:#ff6666">当执行action2时,会把action1中valuestack的值赋给action2的valuestack</span></p>  
<p><span style="color:#ff6666">当执行action3时,会把先后把action1和action2中valuestack的值赋给action3的valuestack</span></p>  
<p><span style="color:#ff6666">依次类推.......</span></p>  
<p> </p>  
<p>再来看下:com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ActionInvocation invocation)</p>  
<p>其中关键方法调用: setParameters(action, stack, parameters);</p>  
<p>把parameters中的内容赋给valuestack</p>  
<p> </p>  
<p>但是,在实际使用过程,不推荐滥用chain</p>  
<p>因为正如之前举的例子一样,当chain上有两个action的时候,</p>  
<p>赋值过程实际上执行了3次=1+2:parameters到action1,action1到action2,parameters到action2</p>  
<p>以此类推:有3个action时,赋值过程=6次=1+2+3</p>  
<p>........</p>  
<p>所以当链条上的action太多时,其实很费油的啦...</p>  
<p>具体过程,空了画个图来表示下,大家就更容易明白了</p>  
<p> </p>  
<p><br>  
 </p>  
<p>
</p>

损失函数大汇总(五十三)(Boundary Loss附公式推导与代码) 摘要 Boundary Loss是一种针对图像分割任务的新型损失函数,特别适用于高度类别不平衡的细粒度分割场景。与传统的区域型损失(如Dice、交叉熵)不同,它通过计算预测边界与真实边界之间的距离来优化模型,更关注边界精度而非区域重叠。核心思想是利用距离图(distance map)将边界约束转化为区域积分形式,实现端到端训练。具体实现中,损失函数为预测概率与距离图的点积,梯度仅取决于距离图,具有明确的空间引导性。相比区域型损失,Boundary Loss能更好处理小目标、细长结构等边界敏感任务,可与Dic 阅读详情

相关推荐

EastWave应用案例:机箱屏蔽效能仿真

如何使用EastWave对机箱的电磁屏蔽效能进行仿真

2201_76034687的博客 1395

浅谈 struts2 之 chain

前一段时间,有关chain的机制着实困绕了许久.尽管网上有许多关于chain的解说,但要不是只谈大理论,不结合实例;要不就是只有示例,没有挖出示例背后的意义.     先解释下chain吧:   Chain:基本用途是构造成一条动作链。前一个动作将控制权转交给后一个动作,而前一个动作的状态在后一个动作里仍然保持着。动作链由Chaining拦截器负责处理,因为这个拦截器是defaultStack

彻底拆分,一切可控! 1530

全栈开发指南:从前端到后端的全面掌握

全栈开发人员(Full Stack Developer)是指能够处理前端和后端开发工作的开发人员。他们需要掌握各种技术和工具,能够独立完成从需求分析、设计、开发到部署的整个流程。这篇博客将详细介绍全栈开发涉及的各个方面,为您提供从入门到进阶的指导。

Where there is a will, there is a way ! 3452

struts2.xml中使用chain和redirectAction这两个注意事项

当在struts.xml中使用chain和redirectAction这两个类型结果的时候,会报检查错误! Multiple annotations found at this line:     - Undefined actionnamespace      parameter     - Undefined actionName parameter 相信不少朋友会被这个错误

随性 5341

别再用默认参数了!手把手教你用2P2Z补偿网络优化Buck电源的动态性能

本文详细介绍了如何通过2P2Z补偿网络优化Buck电源的动态性能,解决默认参数下的负载阶跃响应问题。从频域分析到元件选型,再到实测验证,手把手教你提升相位裕度,显著降低超调量和稳定时间,适用于DCDC和开关电源设计。

weixin_33657398的博客 257

人形机器人核心架构梳理

定义:机器人是能进行运动、操纵或定位且具有一定程度自主能力的可编程执行机构。按外在形态分类可分为传统机器人和人形机器人,其中人形机器人是一种利用人工智能和机器人技术制造的具有类似人类外观和行为的机器人。

小海聊智造 1万+

【struts2】名为chain的ResultType

  1)基本使用   名称为“chain”的ResultType,在struts-default.xml里的配置如下: &lt;result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/&gt;   chain是一种特殊的视图结果,用来将Action执行完之后链接到另一个Action中继续执行...

weixin_33769207的博客 187

新手自己动手设置3D-slicer中文版(超详细图文)

3DSlicer是一个开源的免费软件,用于医学图像分析(包括配准和交互式分割)和可视化(包括3D渲染)以及用于图像引导治疗研究的软件平台。复制qm文件,粘贴于3D-slicer文件相关文件夹内,\bin\translations\。打开3dslicer,edit菜单下Application Settings,支持的操作系统:Linux,Mac OSX和Windows。本人英语太差,所以第一反应就是中文版,官网无中文版下载,下载后不能直接使用,必须要发布成qm文件;qm文件已经生成,位于ts文件同一文件夹。

linjianping513的博客 9854

Struts2注解(annotation)方式下chain的设置方式

最近做一个项目,Struts2+Spring+Hibernate这三个开源框架下的,基本上抛弃了传统的XML配置方式,采用了注解(annotation),的确注解减轻了程序员很多工作量,注入也变得简单多了,只是有些细节还在慢慢适应中: 先来说个“chain”方式跳转的问题 action的访问,我们采用了动态方法调用的方式来访问,也就是使用叹号“!”,有些需求是需要跳转到另一个a

itjoy的专栏 5186

YOLOv11改进 | 集成FEM、FFM与SCAM即插即用模块:特征增强、融合与空间上下文建模新范式

FEM解决特征表达不足问题,增强关键特征响应FFM优化多尺度融合,提升小目标检测精度SCAM建模空间上下文,改善目标交互预测在保持YOLOv11实时性优势的同时,实现mAP+8.1%的显著提升,特别在复杂光照、密集目标、交互预测场景表现突出。其模块化设计使开发者可根据需求灵活组合,为各种复杂场景提供定制化解决方案。未来,随着跨模态扩展与神经架构搜索的深入,YOLOv11-FSC将进一步推动目标检测技术向更智能、更高效的方向发展。

走向CTO的路上... 988

详解vit_base_patch16_224

ViT-Base模型的核心思想是将输入图像划分为多个小块(patches),并使用Transformer架构来处理这些小块。具体来说,ViT-Base使用16x16像素的patch大小,输入图像的尺寸为224x224像素,这意味着每张图像将被划分为49个patch(22416×22416=14×14=19616224​×16224​=14×14=196个patch)。ViT-Base(ViT-B/16)通过将图像处理任务转化为序列处理任务。

具身机器人和通用AI 3227

struts2中chain、redirect和redirectAction的区别

2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。BAT面试经验实战系列:Spring全家桶+Redis等其他相关的电子书:源码+调优面试真题:《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》

2401_83703866的博客 725

Open3D 计算FPFH特征【2025最新版】

FPFH特征描述子的python实现,本文最新更新时间为:2025年3月18日。

点云侠的博客 5275

浅谈struts2之chain[2]

上午写了浅谈struts2之chain[1]>>,现在接着写下半部分:从源码的角度谈chain的机制   因为我的源码全是通过反编译jar包得来,不能保证100%的正确性,若遇到不对的地方,请大家指出.也请大家先谅解   在浅谈struts2之chain[1]>>最后,用了一个简略图来表示chain机制:      但实际上,如果考虑valuestack的话,这幅图应该这样画:

China盼盼 3427

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

浅谈struts2之chain[1]

前一段时间,有关chain的机制着实困绕了许久.尽管网上有许多关于chain的解说,但要不是只谈大理论,不结合实例;要不就是只有示例,没有挖出示例背后的意义.     先解释下chain吧:   Chain:基本用途是构造成一条动作链。前一个动作将控制权转交给后一个动作,而前一个动作的状态在后一个动作里仍然保持着。动作链由Chaining拦截器负责处理,因为这个拦截器是defaultStack

China盼盼 2839

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

浅谈struts2

浅谈struts2一些配置 这篇文章也许是我在csdn上发表的第一篇,有时候真的感觉自己不会说什么,表达能力欠缺,从开始学习程序开始,对我最大的影响的就是csdn博客,我也是在上面看了很多的文章,也学到了很多大牛的分享,到目前为止,我也学到了一点,所以,我也想打算把我所知道的毫无保留的分享给大家,和大家学习。如果写的不好还请大家尽情吐槽。 一、action的基本配置先不说那么多,先上配置文件st

张天壮 1437

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

struts2浅谈其jar包

项目中应用的struts2中的各种jar包的意思已经整理如下 struts2-core.jar——Struts2的核心包  xwork-core.jar——Command模式框架,WebWork和Struts2都基于xwork  commons-logging.jar——Java日志工具类包  freemarker.jar——模板引擎,一个基于模板生成文本输出的通用工具  ognl.ja

xiaofanren1111的博客 452

浅谈Struts2拦截器的原理与实现

一、理解Struts2拦截器 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. 拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺

孙一凡07的专栏 644

道听途说Struts2之15:chain跳转到另外的一个包中的action

这个应该不是什么问题,只是想说明有时候看文档是最简单也是最快速的学习这些东西的方法。          有时候我们做一些东西,认为自己写的是正确的,但是怎么调试修改都不正确,这时候应该是先看文档,然后找搜索引擎,最后才是问老师。如果自己能够解决的,一定要培养自己解决问题的习惯和能力,有时候我们都挺懒的,都想遇到问题就想别人给我解答。但是不是会一直有这么一个人,所以如果想一直能够解决问题,就得培养

孟祥月的专栏 3022

关于struts2的chain

当action的返回结果类型为chain时,chain拦截器就会发生作用,把当前action和目标action都压入值栈。 那么如果目标action的返回结果依然是chain呢?当然也把目标action的目标也压入值栈。 亦即是说,   &lt;action name="a" class="A"&gt; &lt;result name="success" type="chain"...

zhb_1204的专栏 208

关于Struts中结果类型chain的理解

chain 结果类型的基本用途是构成一个 action 链: 前一个 action 把控制权转发给后一个 action, 而前一个 action 的状态在后一个 action 中依然保持 chain 结果类型接受下面这些参数: actionName: 指定目标 action 的名字. 它是默认属性 namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数,

l1252838941的博客 567
上一篇: Struts2配置RESULT中TYPE的参数说明
下一篇: 客户端跳转与服务器端跳转的区别
randomnet
博客等级 码龄19年 59粉丝 21原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值