记录Spring REST API

时间:2018-11-10 17:26:51

标签: java spring logging filter interceptor

我有自定义过滤器,我想根据请求记录正文。 但是当我使用ContentCachingRequestWrapper并尝试调用getContentAsByteArray()时,我总是得到一个空数组。

@Component
public class CustomFilter implements Filter {

    private final Logger log = LoggerFactory.getLogger(CustomFilter.class);

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest requestToCache = new ContentCachingRequestWrapper(request);

        chain.doFilter(req, res);

       log.info(getRequestData(requestToCache));
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    public static String getRequestData(final HttpServletRequest request) throws UnsupportedEncodingException {
        String payload = null;
        ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
        if (wrapper != null) {
            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
            }
        }
        return payload;
    }
  }

我也尝试创建Interceptor,但是有同样的问题。 我究竟做错了什么? 感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以通过在@Configuration带注释的类中注册此bean来使用现有的spring实现:

@Bean
public static Filter requestLoggingFilter() {
    final CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
    loggingFilter.setIncludePayload(true);
    loggingFilter.setMaxPayloadLength(512);

    return loggingFilter;
}

答案 1 :(得分:0)

尽管我建议您使用NiVer的答案,但我一直在调查为什么会发生此问题,我终于可以给您答案。

创建新的ContentCachingRequestWrapper时,内部ByteArrayOutputStream会被初始化,但是不会将任何数据复制到其中。仅当您调用ByteArrayOutputStreamgetParametergetParameterMap()getParameterNames()方法时,主体才会写入getParameterValues(String name),即使这样,仅当内容类型包含application/x-www-form-urlencoded