在Spring Boot REST服务中记录所有请求和响应

时间:2018-06-20 15:13:35

标签: spring spring-boot tomcat

我使用Spring boot并有一些REST控制器。我想记录所有请求和响应。我使用外部tomacat,未嵌入!我写了Interceptor

@Component
@Log4j2
public class LoggingWebMvcInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        final ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request);
        log.debug("REQ!!!! {}", wrapper.getReader().lines().collect(Collectors.joining(System.lineSeparator())));
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //log.debug("Response: {}", response);
    }

并添加他的内容:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final LoggingWebMvcInterceptor loggingWebMvcInterceptor;

    @Autowired
    public WebMvcConfig(LoggingWebMvcInterceptor loggingWebMvcInterceptor) {
        this.loggingWebMvcInterceptor = loggingWebMvcInterceptor;
    }

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

但这不起作用!

当我尝试POST请求时,记录了他的日志,但是我遇到了错误:"Required request body is missing

我在做什么错?我为请求创建了一个包装器! 我需要完全记录所有带有标头和正文以及所有响应的请求(POST,GET,DELETE,PUT)。我怎样才能做到这一点?请帮忙。

3 个答案:

答案 0 :(得分:0)

尽管您的问题并不是每一个都被很好地理解(没有被很好地记录下来-例如,Required request body is missing.所显示的问题来自何处),但还是如此。

出于日志记录的目的,我不愿意使用Interceptor,因为我觉得这很麻烦。相反,您可以很好地用切入点创建一个Aspect,该切入点定义为使用各种Spring控制器注释注释的方法。 ProceedingJoinPointproceed方法有效地使您能够获取响应对象,并且请求本身包含与参数,IP,方法等有关的所有信息。

有了这个,您就可以在其中注入HttpServletRequest,从而最终拥有所有合适的工具来执行任何日志记录活动。

如果您想多次缓存并重新读取HttpServletRequest的正文,那么添加缓存包装确实是非常正确的做法,但是我会避免将其添加到Interceptor / Aspect本身中。

答案 1 :(得分:0)

根据Baeldung文档,ContentCachingRequestWrapper类具有以下限制:

  

ContentCachingRequestWrapper类仅支持以下内容:   内容类型:应用程序/ x-www-form-urlencoded   方法类型:POST

  

我们必须调用以下方法以确保在使用请求数据之前将其缓存在ContentCachingRequestWrapper中:requestCacheWrapperObject.getParameterMap();

https://www.baeldung.com/spring-http-logging

答案 2 :(得分:-2)

您可以将Web过滤器(javax.servlet.Filter)用作:

public class CustomFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp,
        FilterChain chain){
//Log actions heres
chain.doFilter(req, resp);}}

然后在web.xml中将您的过滤器声明为:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>package.CustomFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>