Spring 过滤器无法查看静态页面请求的状态代码

Spring filters cannot see status codes for requests to static pages

我是 运行 一个 Spring Boot Web MVC 应用程序,其中一些页面由控制器处理,而其他页面(静态内容)使用 ResourceHandler 配置。我有自己的控制器方法错误处理。我 运行 它是独立的 Tomcat。

我想记录每个 HTTP 请求及其响应,以及响应的 HTTP 状态代码。使用 Tomcat 访问日志不是一个选项,因为每个请求都有一个上下文(客户端有一个活动会话),我想将会话与请求的页面相关联。

我试过使用过滤器和拦截器进行日志记录。问题是我不能让拦截器看到对静态资源的任何请求——我认为它们只适用于由控制器处理的页面——过滤器将记录对静态资源的请求,但它们总是将响应记录为 200,即使这是一个 404。我还没有设置我自己的默认错误页面(我对设置一个不感兴趣,我只需要设置状态)所以当我请求一个不存在的静态资源时我'我会在我的日志中看到类似这样的内容:

2015-03-26 16:02:46.770  INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter   : CONTEXT=unknown; Type=request; Method=GET; resource=/resources/missing.html
2015-03-26 16:02:46.770  INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter   : CONTEXT=unknown; Type=response; Status=200; Length=unknown; resource=/resources/missing.html
2015-03-26 16:02:46.788  INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter   : CONTEXT=unknown; Type=request; Method=GET; resource=/error
2015-03-26 16:02:46.788  INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter   : CONTEXT=unknown; Type=response; Status=404; Length=unknown; resource=/error
2015-03-26 16:02:46.811  INFO 26576 --- [http-bio-8080-exec-3] a.c.u.a.c.RequestLoggingInterceptor      : CONTEXT=unknown; Type=request; Method=GET; resource=/error
2015-03-26 16:02:46.839  INFO 26576 --- [http-bio-8080-exec-3] a.c.u.a.c.RequestLoggingInterceptor      : CONTEXT=unknown; Type=response; Status=404; Length=unknown; resource=/error

如您所见,只有过滤器为静态资源获取任何 request/response,但过滤器和拦截器稍后都为我丢失的 /error 页面获取请求和响应。

请注意,我有 ,但据我所知,它只影响 DeferredResults - 它不应该影响静态页面请求的过滤器链中状态的外观。

如何记录对缺少静态资源的请求的真实响应状态?我真的不介意这是如何完成的——通过过滤器或使用拦截器或通过覆盖 /error.

的控制器

这是我的 AppConfiguration,它添加了静态资源处理程序和拦截器:

    @Configuration
    @EnableConfigurationProperties
    @EnableWebMvc
    public class AppConfiguration extends WebMvcConfigurerAdapter {

        @Autowired
        private MyAppProperties properties;

        @Autowired
        SessionDataArgumentResolver sessionDataArgumentResolver;

        // Serve up static files directly from the external directory
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {


            registry.addResourceHandler("/resources/**").addResourceLocations(
                    properties.getExternalDirectoryURI("resources/").toString()).setCachePeriod(
                    properties.getCacheControlMaxAge());

            // At least after the controller registry
            registry.setOrder(10);
        }

        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            argumentResolvers.add(sessionDataArgumentResolver);
        }

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new RequestLoggingInterceptor());
        } 

    }

我最终在 Github 上发布了一个问题:https://github.com/spring-projects/spring-boot/issues/2817 答案简单得令人尴尬:我需要记录响应状态 after 调用 filterChain.doFilter:

@Override
protected void doFilterInternal(HttpServletRequest request,     HttpServletResponse response, FilterChain filterChain)
    throws ServletException, IOException {
filterChain.doFilter(request, response);
LOGGER.info("HTTP request for resource {} - status {}", request.getRequestURI(), response.getStatus());
}

这样做之后效果很好。