ContentCachingResponseWrapper создает пустую реакцию

Я пытаюсь реализовать фильтр для регистрации запросов и ответов в приложении Spring MVC . Я использую следующий код:

 @Component public class LoggingFilter extends OncePerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(LoggingFilter.class); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request); ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response); LOGGER.debug(REQUEST_MESSAGE_FORMAT, requestWrapper.getRequestURI(), requestWrapper.getMethod(), requestWrapper.getContentType(), new ServletServerHttpRequest(requestWrapper).getHeaders(), IOUtils.toString(requestWrapper.getInputStream(), UTF_8)); filterChain.doFilter(requestWrapper, responseWrapper); LOGGER.debug(RESPONSE_MESSAGE_FORMAT, responseWrapper.getStatus(), responseWrapper.getContentType(), new ServletServerHttpResponse(responseWrapper).getHeaders(), IOUtils.toString(responseWrapper.getContentInputStream(), UTF_8)); } } 

Таким образом, я получаю свой запрос и отвечаю за регистрацию, как ожидалось. Вот журналы:

 2016-10-08 19:10:11.212 DEBUG 11072 --- [qtp108982313-19] by.kolodyuk.logging.LoggingFilter ---------------------------- ID: 1 URI: /resources/1 Http-Method: GET Content-Type: null Headers: {User-Agent=[curl/7.41.0], Accept=[*/*], Host=[localhost:9015]} Body: -------------------------------------- 2016-10-08 19:10:11.277 DEBUG 11072 --- [qtp108982313-19] by.kolodyuk.logging.LoggingFilter ---------------------------- ID: 1 Response-Code: 200 Content-Type: application/json;charset=UTF-8 Headers: {} Body: {"id":"1"} -------------------------------------- 

Однако возвращается пустой ответ. Вот результат от curl :

 $ curl http://localhost:9015/resources/1 --verbose * Trying ::1... * Connected to localhost (::1) port 9015 (#0) > GET /resources/1 HTTP/1.1 > User-Agent: curl/7.41.0 > Host: localhost:9015 > Accept: */* > < HTTP/1.1 200 OK < Date: Sat, 08 Oct 2016 17:10:11 GMT < Content-Type: application/json;charset=UTF-8 < Content-Length: 0 < * Connection #0 to host localhost left intact 

Есть идеи?

благодаря

После нескольких часов борьбы я наконец нашел решение.

Короче говоря, ContentCachingResponseWrapper.copyBodyToResponse() следует вызывать в конце метода фильтра.

ContentCachingResponseWrapper кэширует тело ответа, читая его из выходного streamа ответа. Итак, stream становится пустым. Чтобы написать ответ обратно в выходной stream, необходимо использовать ContentCachingResponseWrapper.copyBodyToResponse() .

Наконец, решена проблема. Вот идеальное решение:

 import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingResponseWrapper; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.util.Enumeration; import java.util.Map; import static java.nio.charset.StandardCharsets.UTF_8; import static net.logstash.logback.marker.Markers.appendFields; @Component public class LoggingFilter extends OncePerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(LoggingFilter.class); @Autowired private ObjectMapper objectMapper; @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(httpServletRequest); ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(httpServletResponse); filterChain.doFilter(requestWrapper, responseWrapper); String requestUrl = requestWrapper.getRequestURL().toString(); HttpHeaders requestHeaders = new HttpHeaders(); Enumeration headerNames = requestWrapper.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = (String) headerNames.nextElement(); requestHeaders.add(headerName, requestWrapper.getHeader(headerName)); } HttpMethod httpMethod = HttpMethod.valueOf(requestWrapper.getMethod()); Map requestParams = requestWrapper.getParameterMap(); String requestBody = IOUtils.toString(requestWrapper.getInputStream(),UTF_8); JsonNode requestJson = objectMapper.readTree(requestBody); RequestEntity requestEntity = new RequestEntity<>(requestJson,requestHeaders, httpMethod, URI.create(requestUrl)); LOGGER.info(appendFields(requestEntity),"Logging Http Request"); HttpStatus responseStatus = HttpStatus.valueOf(responseWrapper.getStatusCode()); HttpHeaders responseHeaders = new HttpHeaders(); for (String headerName : responseWrapper.getHeaderNames()) { responseHeaders.add(headerName, responseWrapper.getHeader(headerName)); } String responseBody = IOUtils.toString(responseWrapper.getContentInputStream(), UTF_8); JsonNode responseJson = objectMapper.readTree(responseBody); ResponseEntity responseEntity = new ResponseEntity<>(responseJson,responseHeaders,responseStatus); LOGGER.info(appendFields(responseEntity),"Logging Http Response"); responseWrapper.copyBodyToResponse(); } } 
  • Как указать страницу ошибки по умолчанию в web.xml?
  • Как загрузить java-class (а не сервлет), когда сервер tomcat запускает
  • Браузер не может получать / находить относительные ресурсы, такие как CSS, изображения и ссылки при вызове сервлета, который пересылает JSP
  • Окончательная версия Java-версии (J2EE, Java EE, Servlet, JSP, JSTL)
  • Как удалить Cookie в Java-сервлете
  • Отправить файл как multipart через xmlHttpRequest
  • Максимальный размер содержимого параметра POST?
  • Как читать и копировать содержимое streamа вывода ответа сервлета HTTP для ведения журнала
  • Как я могу прочитать выходной stream HttpServletReponses?
  • Лучший вариант для управления сеансами в Java
  • Как удалить заголовок ответа HTTP?
  • Interesting Posts

    Как рисовать штабелированные столбцы в ggplot2, которые показывают процентные ставки по группе?

    Скопированный профиль пользователя, теперь получите «невозможно получить доступ к устройствам … соответствующие разрешения» в системных файлах

    Ошибка кодового знака: идентификатор «iPhone Developer» не соответствует какой-либо действительной паре сертификата / закрытого ключа в ключевом ключе по умолчанию

    Где разместить и как читать файлы ресурсов конфигурации в приложении на основе сервлета?

    Как открыть веб-браузер по умолчанию с помощью java

    Ссылка на объект требуется для нестатического поля, метода или свойства?

    Почему .NET Framework 3.5 не установлен на моем ПК?

    использование «экземпляра» в java

    Как изменить виджет по умолчанию для всех полей даты Django в ModelForm?

    Статический анализ графика вызовов Java

    Что делает «Оптимизация дисков» в Windows 8?

    Опции для встраивания Chromium вместо IE WebBrowser с WPF / C #

    При обработке отчета произошла ошибка. Отчеты -RLDC в ASP.NET MVC

    Можно ли переопределить ключевое слово C ++?

    Bootstrap 3 не может правильно отобразить глификон

    Давайте будем гением компьютера.