gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 09:04:27 24 4
gpt4 key购买 nike

我有一个 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 参数之外,我还需要做更多的事情吗?

稍后编辑:Web应用程序初始化器

    @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 都依赖于 ServletContainerInitializer来自servlet 3.0用于设置 ServletContext 的 API 。问题是它们的执行顺序取决于它们在类路径上扫描的顺序,并且您不能真正依赖它(在您的情况下, 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

关于没有 web.xml log4j 配置的 Spring 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32713596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com