環境:Struts2+Tiles+Spring

一口氣升級
Struts2.3 → 2.5
tiles2 → 3
log4j → log4j2
Spring 4.2.6 → 4.3.8

首先置換所有Spring套件到4.3.8.Final (目前最新) 和
struts2-spring-pluginstruts2-tiles-plugin的版本到2.5.10.1 (有安全性問題,所以要更新到.1這個補丁)

錯誤訊息:

嚴重: Exception starting filter struts2
java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1305)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1139)

(下略)

解法:
修改 web.xml 裡的filter mapping

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

原因:

舊版是 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
新版 (2.5) 把「ng」這層目錄拿掉了,還沿用舊版設定的話會找不到class

REF: https://struts.apache.org/docs/struts-23-to-25-migration.html


JSP方面

escape="true" (2.5) 改成 escapeHtml="true" (2.5)

//舊版 (2.3)
<s:set name="prop1" value="value1"/>
<s:set id="prop2" value="value2"/>

nameid都要改成var

//新版 (2.5)
<s:set var="prop3" value="value3"/>

另外2.3.4那邊有個奇怪的小問題
類似「aSum」這種開頭小寫只有一個字的命名,struts2的getter/setter會抓不到,但改成「aaSum」就可以一切正常
這問題據說修好了,REF: Not set parameter value to Action correctlly

REF:  Struts 2.3 to 2.5 migration


struts.xml

改開頭的宣告成2.5版

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

萬用字元(widecard)處理

在default package加上 strict-method-invocation="false"

<package name="default" namespace="/" extends="tiles-default" strict-method-invocation="false">

REF: Wildcard Action Mapping no longer working after updating to Struts 2.5Strict Method Invocation


tiles.xml

開頭宣告改成3版

<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>


log4j → log4j2

改成2版,要追加JAR檔

    <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
          <version>1.7.25</version>
      </dependency>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-web</artifactId>
        <version>2.8.2</version>
    </dependency>

REF: Logging Spring using Log4j2Using Log4j 2 in Web Applications


web.xml

2.5改成3.1

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" version="3.1">


log4j.properties 檔改成 log4j2.xml,設定範例

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="org.apache.log4j.xml" level="info"/>
        <Root level="debug">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>

這段設定成功的話,啟動時會看見Console跳出大量log info

*記得去pom.xml用Dependency hierarchy檢查還有沒有其他套件用1版的log4j (例如JXL),要把它exclude掉以免出現1版啟動失敗的警告訊息

REF: Migrating from Log4j 1.x


錯誤訊息:

java.lang.NoClassDefFoundError: org/apache/log4j/LogManager
    at org.springframework.util.Log4jConfigurer.shutdownLogging(Log4jConfigurer.java:123)
    at org.springframework.web.util.Log4jWebConfigurer.shutdownLogging(Log4jWebConfigurer.java:172)
.....(中略)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.LogManager

原因:舊設定會啟動系統內已經不存在的log4j (1代),造成找不到檔案的錯誤

解法:web.xml

(1) 直接刪除以下這段,把loj4j2.xml放在WEB-INF下

  <context-param>
    <param-name>
log4jConfigLocation</param-name>
    <param-value>
classpath:log4j.properties</param-value>
  </context-param>

(2) 或把上述參數改成這段,把loj4j2.xml放在class path下

<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>classpath:log4j2.xml</param-value>
  </context-param>

REF: Log4j2.xml configuration in web.xml


 

大功告成......!!!

相關文章