没有web.xml log4j配置的Spring应用程序

时间:2015-09-22 09:42:34

标签: spring jersey log4j log4j2

我有一个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/*");

    }

1 个答案:

答案 0 :(得分:5)

您还需要注册一个监听器:Log4jConfigListener(您可以在org.springframework.web.util中找到它)

servletContext.addListener(Log4jConfigListener.class);

顺便说一下,你可以注意到它自春季4.2.1以来已被弃用

请参阅:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/Log4jConfigListener.html

修改

抱歉,我没有意识到您使用的是log4j 2 , 上述所有内容都是错误的,以下是您的解决方案:

log4j2(感谢log4j-web神器)&amp; spring都依赖于ServletContainerInitializer API中的servlet 3.0来设置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://www.eclipse.org/jetty/documentation/current/using-annotations.html#servlet-container-initializers

http://logging.apache.org/log4j/2.x/manual/webapp.html

修改

POC @ http://www.filedropper.com/32713596_1 只需运行mvn jetty:run