登录@Controller 3.请春季启动(Logging @Controller Requests

2019-10-22 02:18发布

我试图登录我@Controller使用弹簧请求(包括请求名称和数据) @Aspect春天开机。 问题是,当使用@Valid没有有效数据的方法不执行,因为参数解决所发生之前。

我也曾尝试以下解决方案,但他们并没有为我工作:

  1. 执行滤镜 - 它需要缓存流和实现自己的Servlet +流禁用它,以确定在逻辑所有日志请求使用ThreadContext的abbility。
  2. 拦截器 - 我尝试添加拦截这有两个问题,第一个扩展WebMvcAutoConfiguration.EnableWebMvcConfiguration或WebMvcConfigurationSupport导致自动配置不是为了得到我需要将其添加在以后的阶段,因为在预处理它尚未readed数据其次工作。我可以使用ThreadContext和@InitBinder的,我猜,但它仍然留给我的第一个问题,非常不干净的解决方案。

如果任何人有关于如何使用@Valid使用@Aspect其他想法或好的建议这将是非常有益的。 谢谢

Answer 1:

我可以用下面的代码来获得我的目标。

@ControllerAdvice
@Component
public class ControllerLogger {

    @InitBinder
    private void initBinder(WebDataBinder binder,WebRequest webRequest) {
        //log the request and data here .
    }
}


Answer 2:

要登录请求和响应头和身体,你可以注册你的日志过滤器:

package demo;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.io.output.TeeOutputStream;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.DelegatingServletOutputStream;

@Configuration
public class HttpServerConfig {

    private final static Logger LOG = Logger.getLogger(HttpServerConfig.class.getName());

    @Bean
    public FilterRegistrationBean logFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setDispatcherTypes(DispatcherType.REQUEST);
        registration.setFilter(new Filter() {
            @Override
            public void init(FilterConfig fc) throws ServletException {
                LOG.info("Init LOG Request Filter");
            }

            private void logRequest(HttpServletRequest httpReq) throws IOException {
                // log request headers
                LOG.info("### Request Headers:");
                for (String header : Collections.list(httpReq.getHeaderNames())) {
                    LOG.log(Level.INFO, "\t* {0}: {1}", new Object[]{header, httpReq.getHeader(header)});
                }
                // log request body
                Scanner qs = new Scanner(httpReq.getInputStream()).useDelimiter("\\A");
                String qb = qs.hasNext() ? qs.next() : "[empty body]";
                LOG.log(Level.INFO, "### Request body: `{0}` ###", qb);
            }

            private void logResponse(HttpServletResponse httpResp, ByteArrayOutputStream baos) {
                // log response headers
                LOG.log(Level.INFO, "### Response [{0}] Headers:", httpResp.getStatus());
                for (String header : httpResp.getHeaderNames()) {
                    LOG.log(Level.INFO, "\t* {0}: {1}", new Object[]{header, httpResp.getHeader(header)});
                }
                // log response body
                LOG.log(Level.INFO, "### Response body: `{0}` ###", baos.toString());
            }

            @Override
            public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
                logRequest((HttpServletRequest) req);

                HttpServletResponse httpResp = (HttpServletResponse) resp;
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                final PrintStream ps = new PrintStream(baos);
                chain.doFilter(req, new HttpServletResponseWrapper(httpResp) {
                    @Override
                    public ServletOutputStream getOutputStream() throws IOException {
                        return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps));
                    }

                    @Override
                    public PrintWriter getWriter() throws IOException {
                        return new PrintWriter(new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)));
                    }
                });
                logResponse(httpResp, baos);

            }

            @Override
            public void destroy() {
                LOG.info("Destroy LOG Request Filter");
            }
        });
        return registration;
    }
}


文章来源: Logging @Controller Requests Spring Boot