Логирование Spring REST API - PullRequest
       34

Логирование Spring REST API

0 голосов
/ 10 ноября 2018

У меня есть собственный фильтр, и я хочу регистрировать тело из запроса. Но когда я использую 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 голосов
/ 10 ноября 2018

Хотя я бы порекомендовал пойти с ответом NiVer, я изучал причину возникновения этой проблемы и наконец могу дать вам ответ.

Когда вы создаете новый ContentCachingRequestWrapper, внутренний ByteArrayOutputStream инициализируется, но данные на него не копируются . Тело записывается в ByteArrayOutputStream только при вызове методов getParameter, getParameterMap(), getParameterNames() или getParameterValues(String name), и даже тогда данные копируются, только если тип содержимого содержит application/x-www-form-urlencoded.

0 голосов
/ 10 ноября 2018

Вы можете использовать существующую реализацию Spring, просто зарегистрировав этот компонент в @Configuration аннотированном классе:

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

    return loggingFilter;
}
...