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

时间:2015-03-26 05:37:41

标签: http spring-mvc tomcat static servlet-filters

我正在运行一个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

正如您所看到的,只有过滤器会获取静态资源的任何请求/响应,但过滤器和拦截器都会为我丢失的/error页面选择请求和响应。

请注意,我有this issue,但据我所知,它只影响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());
        } 

    }

1 个答案:

答案 0 :(得分:0)

我最后在Github上发布了一个问题:https://github.com/spring-projects/spring-boot/issues/2817 答案很简单:我需要在调用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());
}

这样做后效果很好。