struts升级至2.5.26遇到的各种bug及解决方案

1、背景

    由于struts2自身的漏洞“【安全】关于Struts2 S2-061 远程代码执行漏洞(CVE-2020-17530)”,所以需要将struts2.3.35相关jar升级至2.5.26版本。而项目本身用的是1.6或1.7的JDK,在更新过程中,遇到了许多的问题,所以将遇到的问题及解决方案总结,对JDK1.8的同学也会有帮助的。

2、2.5.26的jar包的内部代码改动

2.1、将xwork-core.jar整合进struts2-core-2.5.26.jar中

    原先的xwork-core.jar是一个独立的jar,在2.5.26版本中,这个jar包被整合进struts2-core.jar当中。
    因此大家在更新jar包的时候除了替换相应的jar包外,还需要删除xwork-core.jar。

2.2、StrutsPrepareAndExecuteFilter路径修改

    原先的路径为org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,现在修改为
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,去掉了“ng.”。
    因此在升级jar之后,原先在web.xml中如果有导入这个类(一般都会有导入),那么需要进行路径替换;或者在自己定义的java类中有引用这个类,也需要进行替换。

2.3、struts2-core-2.5.26中 getParameters()返回类型修改

     getParameters() 方法的完整路径为 com.opensymphony.xwork2.ActionContext.getParameters(),原先返回的类型为 Map<String, Object>,如图
现在返回类型改为了 HttpParameters类型,如图
关于修改的区别,在稍后的bug处理上详细解释 ,此处感谢小林同学 二、Struts2.3.32升级到Struts2.5.26详细步骤(无敌版)

2.4、struts2-core-2.5.26中的 escape()修改为 escapeHtml()

setEscapeHtml()方法所在的完整路径为struts2-core-2.5.26.jar!\org\apache\struts2\views\jsp\PropertyTag.clas
原先的方法名为escape(),这个方法是定义jsp的标签,是否将内容以html代码进行读取

3、升级过程

3.1、2.5.26版本升级包下载地址

3.2、下载出来的压缩包解压

    得到的lib中的jar包有90个,这些jar包有的不支持1.6或者1.7的JDK环境,所以我只更新了其中的核心jar,其它的根据报错信息,一步步解决。替换的jar如下

3.3、修改StrutsPrepareAndExecuteFilter路径

(1)将org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter修改为org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter;
(2)将java类中有导入StrutsPrepareAndExecuteFilter的地方做同步修改,原因见2.2

3.4、jsp标签属性值修改

(1)escape改为改为改为escapeHtml,原因见2.4;
(2)id改为var,注意不是h5的id属性,因为2.5.26中此属性已废除,如下
<s:iterator value="" status="status" var="var">

3.5、struts.xml头文件问题

原来的头文件如下
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

  链接的版本是2.0版本的,很多教程中说要将2.0改成2.5,经过我自己尝试这个修改不是必须的。要想知道原因首先要知道这个头文件的作用。

这个头文件链接的网址其实是一种规范,定义了struts.xml文件中定义的标签是遵循2.0还是2.5的规范,至于具体规范是什么,很容易读,这里就不赘述了。经过我自己查看两个版本差别不大。而我认为既然以前标签没有做修改,那么遵循的规范版本也没必要修改。个人意见,仅供参考!
     至此,理论上的升级就结束了,当然实际上遇到了各种bug,bug及解决方案如下

4、Bug解决

    首先说下这次的更新官方提供的jar包是在是太坑爹了,很多jar都是需要JDK1.8的环境才能运行。只是官方你认为JDK.8流行起来的时候,正经人谁还用struts框架,而我的项目都是1.6、1.7版本的,直接替换官方提供的90个jar怕是老大要拿我祭天的好嘛,所以只替换了步骤3.2中截图到的几个jar,然后开始了漫长的报bug、修bug之路。

4.1.1 bug描述

Caused by: java.lang.NoClassDefFoundError: Lorg/apache/logging/log4j/Logger;

4.1.2 解决方案

添加步骤3.2中的两个log4j的jar包即可

4.2.1 bug描述

Caused by: java.lang.NoSuchMethodError: org.apache.commons.lang3.text.StrSubstitutor.setValueDelimiter(Ljava/lang/String;)Lorg/apache/commons/lang3/text/StrSubstitutor;
at com.opensymphony.xwork2.config.providers.EnvsValueSubstitutor.<init>(EnvsValueSubstitutor.java:35) [struts2-core-2.5.26.jar:2.5.26]

4.2.2 解决方案

Commong-lang.jar升级为3.7版本

4.3.1 bug描述

Caused by: java.lang.NoClassDefFoundError: org/apache/struts2/dispatcher/StrutsResultSupport
at java.lang.ClassLoader.defineClass1(Native Method) [rt.jar:1.7.0_211]
at java.lang.ClassLoader.defineClass(ClassLoader.java:808) [rt.jar:1.7.0_211]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) [rt.jar:1.7.0_211]
at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:326)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:390)
... 32 more

4.3.2解决方案

    添加StrutsResultSupport.class文件,文件内容可以去原来的jar包中获取,位置在org\apache\struts2\dispatcher\StrutsResultSupport.class

4.4.1 bug描述

java.lang.NoSuchMethodError: com.opensymphony.xwork2.ActionContext.getParameters()Ljava/util/Map;

4.4.2解决方案

    查看自己报错的位置,一定是有个地方调用了ActionContext.getParameters()方法,然后再接收时用的Map类型接收,如下
Map<String, Object> map = actionContext.getParameters();
将接收类型改为,如下
HttpParameters map = actionContext.getParameters();

此处这样修改的原因见步骤2.3

4.5.1 bug描述

java.lang.ClassCastException: Parameter  cannot be cast to String

    具体堆栈信息忘记记录了,大抵就是类型转换异常,Parameter 不能转换为 String类型

4.5.2 解决方案

    这个报错和bug4有一定关联,还是未升级前代码
Map<String, Object> map = actionContext.getParameters();
    此处的Map<String, Object>中的object是可以强制转化为String[]的,但是升级后,由于成为了如下的代码。
HttpParameters map = actionContext.getParameters();
HttpParameters继承了Map<String, Parameter>,所以此处自然不能强制转化为String[]了,如果你报了这个异常,说明你是想要取到存储的String[]数组,那么可以使用如下的方法进行获取,想将其用Parameter接收,然后调用getMultipleValues()方法即可。
((Parameter)entry.getValue()).getMultipleValues()

4.6.1 bug描述

java.lang.NoSuchMethodError: org/apache/commons/lang3/reflect/MethodUtils.getAnnotation(Ljava/lang/reflect/Method;Ljava/lang/Class;ZZ)Ljava/lang/annotation/Annotation;

4.6.2 解决方案

在commons-lang3-3.3.1.jar!\org\apache\commons\lang3\reflect\MethodUtils.class文件的末尾处添加getAnnotation()和其依赖的getAllSuperclassesAndInterfaces()的方法

总结

    由于自己项目JDK版本较低,不可能大范围的修改jar包,只能替换一下核心的jar,然后根据报错逐步修改源码或者升级jar包。大家如果有遇到相似的问题可以帮助少走弯路。最后再表达下我对struts框架的无奈!!!
  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值