閱讀388 返回首頁    go 阿裏雲 go 技術社區[雲棲]


struts2改springmvc過程中問題及解決辦法記錄

我們目前的係統中使用了struts2框架,該版本是2.3.32,但近期Apache struts發布了一項struts的安全漏洞說明,具體如下:

Apache Struts2 遠程代碼執行漏洞(S2-048)
發布日期:2017年7月7日
CVE ID:CVE-2017-9791

受影響的版本:

Apache Struts Version: 2.3.x

不受影響的版本:

Apache Struts Version:2.5.10.1

綜述:

2017年7月7日,Apache Struts發布最新的安全公告,Apache Struts2的Struts1插件存在遠程代碼執行的高危漏洞,漏洞編號為CVE-2017-9791(S2-048)。攻擊者可以構造惡意的字段值通過Struts2的Struts1的插件,遠程執行代碼。
相關鏈接如下:
https://cwiki.apache.org/confluence/display/WW/S2-048

規避方案

  1. 關閉Showcase插件。
  2. 受影響的用戶可以升級到2.5.10.1版本。
  3. 開發者通過使用resource keys替代將原始消息直接傳遞給ActionMessage的方式。 如下所示: messages.add("msg", new ActionMessage("struts1.gangsterAdded", gform.getName())); 不要使用如下的方式: messages.add("msg", new ActionMessage("Gangster " + gform.getName() + " was added"));
  4. 在非必要的情況下禁用struts2-struts1-plugin插件。將struts2-struts1-plugin-2.3.x.jar文件從 “/WEB-INF/lib”目錄中移動到其他文件夾或者刪除。

根據apache struts的安全漏洞說明,我們的struts版本剛好是這次說的有問題的版本,因此需要根據官方建議升級為2.5.10.1。
但是綜合項目實際情況後發現,升級到2.5.10.1的struts2後,官方的規範說明明確指出需要使用jdk7以上版本:
1

因此,若要升級struts2,則必須同時升級目前項目中jdk6版本到jdk7。
考慮到項目實際情況,發現如上述的方式改動,升級jdk6到jdk7後,出現的問題將會更大,因此分析研究後決定直接把struts2的框架替換為spring mvc,在解決本次問題的同時,向目前更主流的框架靠攏。

在整個改造過程中問題諸多,以下是部分問題及解決辦法記錄,供以後參考:

1、改造之前,嚐試運行原來的項目,其中有兩個項目mobileFront和mobileFrontQuery,在把兩個項目都加入到同一個tomcat的時候報錯,提示如下:

Could not publish server configuration for Tomcat v7.0 at localhost.
Multiple Contexts have a path of "/mobileFront".

意思是要部署名為mobileFront的項目,但是現在已經存在了一個。
原因是mobileFront和mobileFontQuery的部署名稱都是mobileFront,在同一個tomca中部署兩個相同部署名稱的項目是不被允許的。
解決辦法是更改其中任意一個的部署名稱,使其不衝突,具體更改過程如下:

右鍵項目--》 選擇properties --》 點擊web project settings --》把context root後的名稱改為要部署的新名稱 --》
打開工作空間,也就是項目文件的存儲目錄,找到要更改的項目 --》打開.settings文件夾 --》 用編輯器打開org.eclipse.wst.common.component文件 --》把文件中原本項目相關的名稱都改為新的項目部署名並保存 --》重啟eclipse。

2、依次配置完web.xml,applicationcontext.xml和springmvc.xml,並在controller類以及相應方法中加入相應注解後啟動項目,拋出如下異常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MMarketAction1': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.huateng.mmarket.service.MMarketService

意思是創建MMarketAction1這個bean失敗,因為autowire無法注入MMarketService。
原因是在配置web.xml文件時少了一個spring的監聽器:

<listener>  
    <description>spring監聽器</description>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  </listener>

在web.xml中加入此監聽器,再次啟動tomcat則不再跑出上述異常。

3、啟動tomca時拋出異常:

java.lang.NoSuchMethodError: org.springframework.web.bind.annotation.RequestMapping.consumes()[Ljava/lang/String;

意思是在requestMapping的方法不存在,這個是使用@RequestMapping注解生成url是拋出異常。
原因是在項目中同時存在了兩個spring-web的jar包,一個3.0.5版本,一個3.1.1版本,這兩個包中都有這個類,包名一樣,導致走到這裏無法確定該用哪個,最終找不到。
解決辦法是去掉3.0.5的jar包,重啟tomca後正常。

4、啟動tomcat沒有拋出異常,但是訪問項目時始終提示404,最終發現在tomcat的項目部署路徑下的WEB-INF中沒有web.xml文件,也就是說這個項目並沒有成功部署到tomcat中。
原因是在build path中少了webapp的引入,導致部署的時候並沒有掃描webapp下的文件,原本build中如下:
2

解決辦法是在build中加入webapp的文件夾,加入後如下:
3

然後clean之後重啟tomcat,可正常訪問。

5、有同事在正常啟動tomcat之後,卻無法正常訪問,原因是部署名並不是項目名,而他使用項目名稱訪問,自然就一直是404。解決辦法是把部署名稱換成項目名稱,或者使用實際部署名稱訪問。

6、struts的action類更改為spring mvc的controller,原struts2情況下,所有action都繼承了ActionSupport,並在struts.xml中進行了類似下邊的配置:

<action name="rcvSpdbPage" 
method="receive"></action>

name定義url,class定義url對應的具體類,method定義入口方法。
改為springmvc後,去掉對ActionSupport的繼承,去掉struts.xml的配置,取代的是在類名上加@controller注解以及在方法上加@RequestMapping注解。
還有一種情況是,需要返回jsp頁麵,原struts中配置如下:

<action name="rcvSPDBReceive" 
    method="receive">
   <result name="signPage">/CmuSpdbResultSign.jsp</result>
</action>

改為springmvc後,除開上一中無返回值一樣的改法外,還需要更改方法的返回值為ModelAndView
同時在代碼中return “signPage”的地方,改為

return new ModelAndView("/CmuSpdbResultSign.jsp");

最後更新:2017-09-12 13:32:30

  上一篇:go  jdk1.6環境下struts2改spring boot方案
  下一篇:go  修改jenkins目錄和端口及啟動用戶