[Struts2] 2.3升級到2.5
環境: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-plugin和struts2-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"/>
name和id都要改成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.5、Strict 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 Log4j2、Using 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版啟動失敗的警告訊息
錯誤訊息:
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
大功告成......!!!