`
zl5897
  • 浏览: 3191 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

struts 2.2.1 中ActionChainResult的修改[CSDN迁移文章]

阅读更多

如果你因struts2暴露的安全漏洞 而希望升级到struts 2.2.1,那么你需要仔细测试你的程序是否能在2.2.1的环境下顺利运行。因为struts 2.2.1版本升级了OGNL、freemarker,以及对我们代码影响很大的xwork。

其中xwork的一个bug编号为"WW-2869 "的修订,对我们熟悉的chain result type做了重要的修改。这个bug的出发点是在一个Action a执行后,跳转到执行result。假设这个result是一张jsp页面,而这张jsp页面中调用了<s:action name="bar"/>标签。假设在执行a Action时,执行了类似代码"addActionError("an error from FooAction");",那么会停止对Action bar的正确调用,而执行Action bar的input。

这个问题的归结原因是在ChainingInterceptor中,在调用Action bar前,会将上一个Action(面假设中的Action a)的一些属性值拷贝到bar中。以下是在strtus 2.2.1前的xwork中的ChainingInterceptor代码

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ValueStack stack = invocation.getStack();
        CompoundRoot root = stack.getRoot();
        if (root.size() > 1) {
            List<CompoundRoot> list = new ArrayList<CompoundRoot>(root);
            list.remove(0);
            Collections.reverse(list);
            Map<String, Object> ctxMap = invocation.getInvocationContext().getContextMap();
            Iterator<CompoundRoot> iterator = list.iterator();
            int index = 1; // starts with 1, 0 has been removed
            while (iterator.hasNext()) {
            	index = index + 1;
                Object o = iterator.next();
                if (o != null) {
                	if (!(o instanceof Unchainable)) {
						//拷贝属性值到将要执行的Action中
                		reflectionProvider.copy(o, invocation.getAction(), ctxMap, excludes, includes);
                	}
                }
                else {
                	LOG.warn("compound root element at index "+index+" is null");
                }
            }
        }
 

对于这种方式的好处,我们或许已经默默的在使用了。还是前面提到的Action a和Action bar,若Action a和Action bar都有一个共同的属性叫common,并且都有get、set方法。那么在Action a中的一些处理后,属性common有了值,经过chain resultType时,Action bar的common会自动被赋值。如果你在升级到struts2.2.1后,发现一些请求返回了NullPointerException,那么很有可 能是struts2.2.1对ChainingInterceptor的修改导致了这个问题。

以下是struts 2.2.1中的ChainingInterceptor源代码

    public String intercept(ActionInvocation invocation) throws Exception {
        ValueStack stack = invocation.getStack();
        CompoundRoot root = stack.getRoot();
        if (root.size() > 1 && isChainResult(invocation)) {
            List<CompoundRoot> list = new ArrayList<CompoundRoot>(root);
            list.remove(0);
            Collections.reverse(list);
            Map<String, Object> ctxMap = invocation.getInvocationContext().getContextMap();
            Iterator<CompoundRoot> iterator = list.iterator();
            int index = 1; // starts with 1, 0 has been removed
            while (iterator.hasNext()) {
                index = index + 1;
                Object o = iterator.next();
                if (o != null) {
                    if (!(o instanceof Unchainable)) {
                        reflectionProvider.copy(o, invocation.getAction(), ctxMap, excludes, includes);
                    }
                } else {
                    LOG.warn("compound root element at index " + index + " is null");
                }
            }
        }
        return invocation.invoke();
    }
 

和前面的相比,if (root.size() > 1) 中对了一个判断isChainResult(invocation)。这个判断让我有些纳闷,因为根据我的一些跟踪,在ActionInvocation 调用invoke()方法前,ActionInvocation中的result属性是null,所以这个if总是false。难道有什么其他设置能恢复 原来类似功能吗?希望有高人解答。正是因为这个问题,若你还希望使用原来chain的拷贝功能,你需要删除 isChainResult(invocation)这个判断。

以下是一个很有趣的实验,首先我们看核心的struts.xml配置信息:

    <package name="default" namespace="/" extends="struts-default">
        <!-- <default-action-ref name="index" /> -->
        <action name="index">
            <result>index.jsp</result>
        </action>
        
        <action name="chainSrc" class="ChainSrcAction">
        	<result type="chain">chainDest</result>
        </action>
         <action name="chainDest" class="ChainDestAction">
        	<result>chainDest.jsp</result>
        </action>
        
    </package>
 

ChainSrcAction的源代码:

import com.opensymphony.xwork2.ActionSupport;
public class ChainSrcAction extends ActionSupport {
	
	private String p1;
	private String p2 = "chain";
	@Override
	public String execute() throws Exception {
		System.out.println(ChainSrcAction.class+"p1="+p1);
		System.out.println(ChainSrcAction.class+"p2="+p2);
		return SUCCESS;
	}
	
	public String getP1() {
		return p1;
	}
	public void setP1(String p1) {
		this.p1 = p1;
	}
	public String getP2() {
		return p2;
	}
}
 

ChainDestAction的源代码:

import com.opensymphony.xwork2.ActionSupport;
public class ChainDestAction extends ActionSupport {
	
	private String p1;
	private String p2 ;
	@Override
	public String execute() throws Exception {
		System.out.println(ChainDestAction.class+"p1="+p1);
		System.out.println(ChainDestAction.class+"p2="+p2);
		return SUCCESS;
	}
	
	public String getP1() {
		return p1;
	}
	public void setP1(String p1) {
		this.p1 = p1;
	}
	public String getP2() {
		return p2;
	}
	public void setP2(String p2) {
		this.p2 = p2;
	}
}
 

在struts 2.2.1的环境下,在地址栏上输入"http://127.0.0.1/s221/chainSrc.action?p1=struts2.2.1"你将会得到以下答案:

class ChainSrcActionp1=struts2.2.1
class ChainSrcActionp2=chain
class ChainDestActionp1=struts2.2.1
class ChainDestActionp2=null

在struts 2.1.8的环境下,相同的访问你会得到答案:

class ChainSrcActionp1=struts2.2.1
class ChainSrcActionp2=chain
class ChainDestActionp1=struts2.2.1
class ChainDestActionp2=chain

如果你将ChainingInterceptor中的if (root.size() > 1 && isChainResult(invocation))改为if (root.size() > 1 ),你也可以得到struts 2.1.8的结果。对于熟悉p1,它始终都得到了赋值是因为还有ParametersInterceptor对它赋值。

分享到:
评论

相关推荐

    Struts2.2.1帮助文档

    Struts2.2.1 api, Struts2.2.1帮助文档, CHM格式文件

    struts2.2.1开发文档

    2. **安装与配置**:详细说明如何在项目中集成Struts2.2.1,包括添加依赖库、配置web.xml文件,以及理解Struts2的核心配置文件struts.xml。 3. **动作(Action)**:解释了Action类在Struts2中的核心地位,它是处理...

    struts2.2.1-core

    Struts2.2.1是Apache Struts框架的一个版本,这是一个流行且强大的Java Web应用程序开发框架,用于构建和维护MVC(模型-视图-控制器)架构的应用程序。该框架的核心在于提供了一种灵活的方式来组织和控制应用程序的...

    MyEclipse7.5+flex4+spring3.0.5+struts2.2.1+hibernate3.6.0+blazeds4.0.0.14931完美整合方案

    在IT行业中,构建一个高效的开发环境对于提升项目质量和开发效率至关重要。本方案提供了一种集成化的开发环境,即"MyEclipse7.5+flex4+spring3.0.5+struts2.2.1+hibernate3.6.0+blazeds4.0.0.14931完美整合方案",它...

    struts2.2.1jar包

    下面我们将深入探讨Struts2框架及其2.2.1版本中的关键组件和功能。 1. **Struts2框架核心**: - `struts2-core-2.2.1.jar`:这是Struts2的核心库,包含了处理HTTP请求、执行Action、处理结果以及与视图交互的所有...

    struts2.2.1 API chm格式

    欢迎大家下载,struts2.2.1 API chm格式

    struts2.2.1开发包

    Struts2.2.1开发包是一个针对Web应用的重要框架,它是Apache软件基金会下的一个开源项目,主要用于构建基于Java的企业级应用程序。这个版本的Struts2是一个强大的MVC(Model-View-Controller)框架,旨在简化开发...

    struts2.2.1-xwork

    Struts2.2.1是Apache Struts框架的一个版本,它是基于MVC(Model-View-Controller)设计模式的开源Java Web应用框架。Struts2是Struts1的升级版,它提供了更强大的功能和更好的性能。XWork是Struts2的核心组件,负责...

    已配置好Struts2.2.1GA的WEB-INF

    在Struts2.2.1GA版本中,这个框架已经相当成熟,提供了一套完整的功能和插件来简化开发流程。 标题中的“已配置好Struts2.2.1GA的WEB-INF”指的是一个已经包含了所有必要配置文件和库的WEB-INF目录,这个目录是Java...

    struts2.2.1chm帮助文档

    struts2.2.1帮助文档,chm格式,让您在学习struts时边学边查阅,方便快捷

    Struts2.2.1关键jar包

    Struts2.2.1是Apache Struts框架的一个版本,它是基于MVC(Model-View-Controller)设计模式的开源Web应用框架,用于构建企业级Java Web应用程序。这个关键jar包包含了Struts2运行所必需的类库,使得开发者能够方便...

    struts2.2.1_help文档

    Struts2.2.1是Apache软件基金会下的一个开源MVC框架,主要用于构建Java Web应用程序。这个"struts2.2.1_help文档"提供的是一份详细的帮助文档,旨在协助开发者理解和使用Struts2.2.1框架进行开发工作。CHM(Compiled...

    Spring 3.0+Hibernate 3.6+Struts2.2.1详解

    在本项目中,我们探讨了如何整合Spring 3.0、Hibernate 3.6和Struts2.2.1这三大框架,以构建一个高效、灵活的企业级Web应用程序。这三者结合,提供了模型-视图-控制器(MVC)架构、持久层管理和AOP(面向切面编程)...

    struts2.2.1-API.chm (索引)

    struts2.2.1-API.chm 方便实用,支持索引,提高工作效率 与大伙分享

    Struts2.2.1+Spring3.1.0.M2+Hibernate3.5.1整合配置demo

    Struts2.2.1+Spring3.1.0.M2+Hibernate3.5.1是经典的Java企业级开发框架组合,通常被称为SSH框架。这个整合配置Demo旨在演示如何将这三个强大的框架集成在一起,实现MVC(模型-视图-控制器)架构,提供数据持久化和...

    struts2.2.1Jar包集合

    在本文中,我们将深入探讨Struts2.2.1版本中的关键知识点,这个版本是Struts2框架的一个重要里程碑。 1. **MVC模式**:Struts2遵循Model-View-Controller(MVC)设计模式,它将业务逻辑、数据表示和用户界面分离,...

    struts2.2.1 包

    Struts2.2.1中的核心概念和特性包括: 1. **Action类**:在Struts2中,Action类是业务逻辑的载体,它负责处理来自用户的请求,并返回一个结果。Action类通常继承自`com.opensymphony.xwork2.ActionSupport`或其子类...

    spring3.0.5_hibernate3.5.3_struts2.2.1整合jar包

    标题中的"spring3.0.5_hibernate3.5.3_struts2.2.1整合jar包"指的是一个集合了Spring 3.0.5、Hibernate 3.5.3和Struts 2.2.1框架的整合包。这个资源是经过作者亲自测试的,被认为是最优的选择。它不仅提供了这三个...

    Struts_2.2.1_lib

    在深入讲解Struts 2.2.1的核心类库之前,我们首先需要理解什么是Struts 2以及它在软件开发中的作用。 Struts 2 是Apache软件基金会开发的一个开源框架,用于构建基于Java Servlet的Web应用程序。它是在原有的Struts...

    struts_2.2.1_src.zip

    在这个"struts_2.2.1_src.zip"压缩包中,包含了Struts 2.2.1的源代码,对于开发者来说,这是一份宝贵的学习和调试资源。 首先,让我们深入了解Struts 2的核心概念和组件: 1. **Action类**:在Struts 2中,Action...

Global site tag (gtag.js) - Google Analytics