Spring Boot - 如何将500响应体日志记录到控制台

3

我已经为Spring(使用Spring Boot v1.5)创建了一个过滤器,该过滤器使用OncePerRequestFilter在每个请求上触发,如下所示:

@Component
class LogRequestFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(LogRequestFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);

        int responseStatus = wrappedResponse.getStatusCode();

        if (responseStatus == 500) {
            String requestUri = wrappedRequest.getRequestURI();
            byte[] responseBodyBytes = wrappedResponse.getContentAsByteArray();
            logger.error("{}, {}, {}", responseStatus, requestUri, new String(responseBodyBytes));
        }

        filterChain.doFilter(wrappedRequest, response);
    }
}

我的问题是当出现错误时,我需要记录响应正文。但是即使用户从Spring接收到以下响应,我也无法从getContentAsByteArray()获取任何数据:

{
    "timestamp": 1512745726835,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "java.lang.NullPointerException",
    "message": "No message available",
    "path": "/documents/2017-02-17"
}

在调试过程中,我可以看到请求的URI是正确的,但是响应体却丢失了。我该如何解决这个问题?


请查看这个答案 - Essex Boy
1
他正在使用ContentCachingResponseWrapper,这是专门为此情况设计的。不过,要在没有文档的情况下使用它有点棘手。 - Gorazd Rebolj
@Gorazd 我同意,刚给你点了赞,我认为你可以为下一个人展示代码。 - Essex Boy
我发现我可以使用上述代码访问所有返回200 OK的请求。只有500响应体没有传递到过滤器。 - onurhb
我认为这里没有主体。 - Essex Boy
1个回答

2
将您的doFilter方法调用移动到读取wrappedResponse内容之前。 在最后调用wrappedResponse.copyBodyToResponse()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接