【问题标题】:Logging all request and response in Spring Boot REST service在 Spring Boot REST 服务中记录所有请求和响应
【发布时间】:2018-11-29 18:51:26
【问题描述】:

我使用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)。我怎样才能做到这一点?请帮忙。

【问题讨论】:

  • 能否请您发布您的控制器类!
  • 请包含您发送的请求数据,并说明您是在请求日志拦截器不工作的帮助,还是发布请求不工作

标签: spring spring-boot tomcat


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    虽然您的问题并不是每个人都很好理解(没有很好地记录——例如,没有显示出问题的来源Required request body is missing.),但无论如何。

    出于记录目的,我不会使用Interceptor,因为我觉得这工作量太大。相反,您可以很好地创建一个切入点,该切入点定义为使用各种 Spring 控制器注释注释的方法。 ProceedingJoinPoint#proceed 方法有效地允许您获取响应对象,并且请求本身包含有关参数、IP、方法等所需的所有信息。

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

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

    【讨论】:

    • 你能举个例子吗?我只想记录来自我的服务的请求和响应,我认为这并不难
    • @All_Safe 它不是,尽管 Aspect 方法可能需要您添加一些额外的代码来将响应呈现为可记录的字符串。除此之外,其余的都非常简单。对日志方面的简单搜索会出现很多结果。
    【解决方案3】:

    您可以使用网络过滤器(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>
    

    【讨论】:

      猜你喜欢
      • 2019-03-26
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2010-12-16
      相关资源
      最近更新 更多