Log4j1.x升级Log4j2.x后Tomcat过滤器配置获取值为空求助
Log4j 1.x升级到2.x后Tomcat过滤器初始化及配置错误解决
问题背景
Tomcat 9环境中,web.xml配置了自定义NewSession过滤器,使用Log4j 1.x时运行正常。升级到Log4j 2.17.1后,启动Tomcat出现以下错误,放回log4j-1.2.15.jar可恢复,但必须使用Log4j 2.x版本。
原web.xml过滤器配置
<filter> <filter-name>newsession</filter-name> <display-name>newsession</display-name> <description>newsession</description> <filter-class>com.demo.custom.filter.NewSession</filter-class> <init-param> <param-name>DomainName</param-name> <param-value>.testlab.com</param-value> </init-param> <init-param> <param-name>DomConfigFile</param-name> <param-value>/opt/tomcat/webapp/demoapp/WEB-INF/classes/NAM_log4j.xml</param-value> </init-param> <init-param> <param-name>customPropFile</param-name> <param-value>/opt/tomcat/webapp/demoapp/WEB-INF/classes/custom_resources.properties</param-value> </init-param> </filter> <filter-mapping> <filter-name>newsession</filter-name> <url-pattern>/idff/sso</url-pattern> </filter-mapping>
启动错误日志
ERROR com.demo.custom.filter.NewSession - No transformation given ERROR com.demo.custom.filter.NewSession - domConfigFile got null from web.xml, setting hardcoded value ERROR com.demo.custom.filter.NewSession - custom_resources got null from web.xml, setting hardcoded value main ERROR Error processing element category ([Configuration: null]): CLASS_NOT_FOUND main ERROR Unknown object "root" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"]
过滤器Java代码片段
package com.demo.custom.filter; import javax.servlet.Filter; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; @WebFilter({ "/NewSession" }) public class NewSession implements Filter { static class FilteredRequest extends HttpServletRequestWrapper { public FilteredRequest(ServletRequest request) { super((HttpServletRequest)request); } public String getParameter(String paramName) { String value = super.getParameter(paramName); // 省略业务逻辑 return value; } public static String decryptValue(String value){ String decryptvalue = null; // 省略解密逻辑 return decryptvalue; } } private static String domainName = null; private static String domConfigFile=null; private static Logger myLogger = LogManager.getLogger(NewSession.class); private String custom_resources; public void init(FilterConfig fConfig) throws ServletException { try{ domainName = fConfig.getInitParameter("DomainName"); domConfigFile=fConfig.getInitParameter("DomConfigFile"); custom_resources=fConfig.getInitParameter("customPropFile"); }catch(Exception e){ myLogger.error(e.getMessage()); } if(domainName == null){ domainName = ".testlab.com"; } if(domConfigFile==null){ myLogger.error("domConfigFile got null from web.xml, setting hardcoded value"); domConfigFile = "/opt/tomcat/webapp/demoapp/WEB-INF/classes/NAM_log4j.xml"; } if(custom_resources==null){ myLogger.error("custom_resources got null from web.xml, setting hardcoded value"); custom_resources = "/opt/tomcat/webapp/demoapp/WEB-INF/classes/custom_resources.properties"; } } // 省略doFilter、destroy方法 }
问题分析
- 过滤器初始化参数失效:过滤器类同时使用
@WebFilter注解和web.xml配置,Tomcat中注解配置优先级高于web.xml,而@WebFilter未定义初始化参数,导致fConfig.getInitParameter()无法获取web.xml中配置的值。 - Log4j配置文件格式不兼容:
NAM_log4j.xml是Log4j 1.x的配置格式,其中<category>、直接放置的<root>元素不符合Log4j 2.x的配置规范,导致初始化报错。
解决方案
1. 修复过滤器参数获取问题
移除过滤器类上的@WebFilter({ "/NewSession" })注解,完全依赖web.xml的过滤器配置,确保初始化参数能被正确读取。修改后的代码片段:
package com.demo.custom.filter; import javax.servlet.Filter; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; // 移除@WebFilter注解 public class NewSession implements Filter { // 其余代码保持不变 }
2. 迁移Log4j 1.x配置到Log4j 2.x格式
将原NAM_log4j.xml转换为Log4j 2.x的XML格式,核心变化:
- 根元素改为
<Configuration>,指定Log4j 2.x命名空间 <category>替换为<Logger>,放置在<Loggers>节点下<root>必须嵌套在<Loggers>节点内- 新增
<Appenders>节点管理输出目标
示例转换后的配置:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" xmlns="http://logging.apache.org/log4j/2.0/config"> <!-- 配置输出目标(Appender) --> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <!-- 可添加File、RollingFile等其他Appender --> </Appenders> <!-- 配置日志器 --> <Loggers> <!-- 对应原Log4j1.x的<category> --> <Logger name="com.demo" level="info" additivity="false"> <AppenderRef ref="Console"/> </Logger> <!-- 根日志器 --> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
3. 清理依赖确保仅使用Log4j 2.x
检查项目依赖和Tomcat/lib目录,移除所有Log4j 1.x相关jar包(如log4j-1.2.15.jar),保留以下Log4j 2.x核心依赖:
log4j-core-2.17.1.jarlog4j-api-2.17.1.jar- 若项目使用SLF4J,需添加
log4j-slf4j-impl-2.17.1.jar作为桥接包
验证
- 部署修改后的过滤器类
- 替换
NAM_log4j.xml为Log4j 2.x格式配置 - 清理Tomcat的
work目录,重启服务 - 检查启动日志,确认:
- 过滤器能正确读取web.xml中的初始化参数,无
got null错误 - Log4j 2.x初始化无
CLASS_NOT_FOUND或元素错误
- 过滤器能正确读取web.xml中的初始化参数,无
内容的提问来源于stack exchange,提问作者user3441151
相关产品推荐
相关产品推荐

