Logging response body (HTML) from HttpServletResponse using Spring MVC HandlerInterceptorAdapter

后端 未结 5 2129
夕颜
夕颜 2020-12-03 05:11

I am trying to log (just to console write now for simplicity sake) the final rendered HTML that will be returned by the HttpServletResponse. (i.e. the body) To this end, I a

5条回答
  •  执笔经年
    2020-12-03 05:28

    the code pasted below works with my tests and can be downloaded from my github project, sharing after applying a solution based on that on a production project

        @Configuration
    public class LoggingFilter extends GenericFilterBean {
    
        /**
         * It's important that you actually register your filter this way rather then just annotating it
         * as @Component as you need to be able to set for which "DispatcherType"s to enable the filter
         * (see point *1*)
         * 
         * @return
         */
        @Bean
        public FilterRegistrationBean initFilter() {
            FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
            registrationBean.setFilter(new LoggingFilter());
    
            // *1* make sure you sett all dispatcher types if you want the filter to log upon
            registrationBean.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
    
            // *2* this should put your filter above any other filter
            registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    
            return registrationBean;
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
    
            ContentCachingRequestWrapper wreq = 
                new ContentCachingRequestWrapper(
                    (HttpServletRequest) request);
    
            ContentCachingResponseWrapper wres = 
                new ContentCachingResponseWrapper(
                    (HttpServletResponse) response);
    
            try {
    
                // let it be ...
                chain.doFilter(wreq, wres);
    
                // makes sure that the input is read (e.g. in 404 it may not be)
                while (wreq.getInputStream().read() >= 0);
    
                System.out.printf("=== REQUEST%n%s%n=== end request%n",
                        new String(wreq.getContentAsByteArray()));
    
                // Do whatever logging you wish here, in this case I'm writing request 
                // and response to system out which is probably not what you wish to do
                System.out.printf("=== RESPONSE%n%s%n=== end response%n",
                        new String(wres.getContentAsByteArray()));
    
                // this is specific of the "ContentCachingResponseWrapper" we are relying on, 
                // make sure you call it after you read the content from the response
                wres.copyBodyToResponse();
    
                // One more point, in case of redirect this will be called twice! beware to handle that
                // somewhat
    
            } catch (Throwable t) {
                // Do whatever logging you whish here, too
                // here you should also be logging the error!!!
                throw t;
            }
    
        }
    }
    

提交回复
热议问题