Spring 没有 web.xml log4j 配置的应用程序
Spring application without web.xml log4j configuration
我有一个 Spring + Jersey Web 应用程序,我正在从 web.xml 迁移到注释基础配置。我正在实施 WebApplicationInitializer,除 log4j 外一切正常,因为我有一个自定义文件名。
在 web.xml 我有
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>/WEB-INF/custom-name-log4j.xml</param-value>
</context-param>
这有效。
现在,我尝试在 Java 中做同样的事情:
container.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
这不起作用...我在 Tomcat 7.0.62 中收到以下错误:
ERROR StatusLogger No Log4j context configuration provided. This is very unusual.
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
我的 WAR 文件包含 WEB-INF/ 文件夹中的 xml。
除了指定 log4jConfiguration 参数,我还需要做更多的事情吗?
稍后编辑:
WebApplicationInitializer
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(MyApplicationConfiguration.class);
container.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
rootContext.setConfigLocation("my.package.spring");
final FilterRegistration.Dynamic characterEncodingFilter = container.addFilter("characterEncodingFilter", new CharacterEncodingFilter());
characterEncodingFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "true");
container.setInitParameter("spring.profiles.default", "prod");
rootContext.register(SecurityContextFilter.class);
container.addListener(new ContextLoaderListener(rootContext));
container.addListener(new RequestContextListener());
container.setInitParameter("contextConfigLocation", "");
final ServletContainer servlet = new ServletContainer();
final ServletRegistration.Dynamic appServlet = container.addServlet("appServlet", servlet);
appServlet.setInitParameter("jersey.config.server.provider.packages", "my.package");
appServlet.setLoadOnStartup(1);
final Set<String> mappingConflicts = appServlet.addMapping("/rest/*");
}
您还需要注册一个监听器:Log4jConfigListener
(您可以在org.springframework.web.util中找到它)
servletContext.addListener(Log4jConfigListener.class);
顺便说一句,你可以注意到它是deprecated since spring 4.2.1
编辑
抱歉,我没有意识到您正在使用 log4j2,
上面所说的一切都是错误的,这里是你的解决方案:
log4j2(感谢 log4j-web
工件)和 spring 都依赖于 servlet 3.0
API 中的 ServletContainerInitializer
来设置 ServletContext
.
问题是它们的执行顺序取决于它们在类路径上扫描的顺序,你不能真正依赖它(在你的情况下, Log4jServletContainerInitializer
启动方法在 SpringServletContainerInitializer
).
要更正此问题,您可以声明自己的 ServletContainerInitializer
实现,我们将在其他人之前(在扫描类路径之前)考虑它,这里是一个示例:
public class Log4j2ConfigServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
ctx.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
}
}
然后你必须创建一个文件:
/META-INF/services/javax.servlet.ServletContainerInitializer
并放入其中:
example.initializer.Log4j2ConfigServletContainerInitializer
(根据您的需要进行更改)
您提供的用于设置自定义 log4j 配置文件位置的配置将在触发 Log4jServletContainerInitializer
之前设置,一切都会好起来的。
见:
https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html
http://logging.apache.org/log4j/2.x/manual/webapp.html
编辑
POC @ http://www.filedropper.com/32713596_1
只是 运行 mvn jetty:run
我有一个 Spring + Jersey Web 应用程序,我正在从 web.xml 迁移到注释基础配置。我正在实施 WebApplicationInitializer,除 log4j 外一切正常,因为我有一个自定义文件名。
在 web.xml 我有
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>/WEB-INF/custom-name-log4j.xml</param-value>
</context-param>
这有效。
现在,我尝试在 Java 中做同样的事情:
container.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
这不起作用...我在 Tomcat 7.0.62 中收到以下错误:
ERROR StatusLogger No Log4j context configuration provided. This is very unusual.
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
我的 WAR 文件包含 WEB-INF/ 文件夹中的 xml。
除了指定 log4jConfiguration 参数,我还需要做更多的事情吗?
稍后编辑: WebApplicationInitializer
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(MyApplicationConfiguration.class);
container.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
rootContext.setConfigLocation("my.package.spring");
final FilterRegistration.Dynamic characterEncodingFilter = container.addFilter("characterEncodingFilter", new CharacterEncodingFilter());
characterEncodingFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "true");
container.setInitParameter("spring.profiles.default", "prod");
rootContext.register(SecurityContextFilter.class);
container.addListener(new ContextLoaderListener(rootContext));
container.addListener(new RequestContextListener());
container.setInitParameter("contextConfigLocation", "");
final ServletContainer servlet = new ServletContainer();
final ServletRegistration.Dynamic appServlet = container.addServlet("appServlet", servlet);
appServlet.setInitParameter("jersey.config.server.provider.packages", "my.package");
appServlet.setLoadOnStartup(1);
final Set<String> mappingConflicts = appServlet.addMapping("/rest/*");
}
您还需要注册一个监听器:Log4jConfigListener
(您可以在org.springframework.web.util中找到它)
servletContext.addListener(Log4jConfigListener.class);
顺便说一句,你可以注意到它是deprecated since spring 4.2.1
编辑
抱歉,我没有意识到您正在使用 log4j2, 上面所说的一切都是错误的,这里是你的解决方案:
log4j2(感谢 log4j-web
工件)和 spring 都依赖于 servlet 3.0
API 中的 ServletContainerInitializer
来设置 ServletContext
.
问题是它们的执行顺序取决于它们在类路径上扫描的顺序,你不能真正依赖它(在你的情况下, Log4jServletContainerInitializer
启动方法在 SpringServletContainerInitializer
).
要更正此问题,您可以声明自己的 ServletContainerInitializer
实现,我们将在其他人之前(在扫描类路径之前)考虑它,这里是一个示例:
public class Log4j2ConfigServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
ctx.setInitParameter("log4jConfiguration", "/WEB-INF/custom-name-log4j.xml");
}
}
然后你必须创建一个文件:
/META-INF/services/javax.servlet.ServletContainerInitializer
并放入其中:
example.initializer.Log4j2ConfigServletContainerInitializer
(根据您的需要进行更改)
您提供的用于设置自定义 log4j 配置文件位置的配置将在触发 Log4jServletContainerInitializer
之前设置,一切都会好起来的。
见:
https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html
http://logging.apache.org/log4j/2.x/manual/webapp.html
编辑
POC @ http://www.filedropper.com/32713596_1
只是 运行 mvn jetty:run