0

I have implemented the below method to log response , but it throws an exception at IOUtils.toString(responseWrapper.getContentInputStream(), "UTF-8"); saying response has zero bytes . I am able to access headers and status. how can I get the response body?

    @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    System.out.println("after Request");
    ObjectMapper objectMapper = new ObjectMapper();

    ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
    HttpStatus responseStatus = HttpStatus.valueOf(responseWrapper.getStatusCode());
    System.out.println(responseWrapper.getStatusCode());
    HttpHeaders responseHeaders = new HttpHeaders();
    for (String headerName : responseWrapper.getHeaderNames()) {
        System.out.println(headerName);
      responseHeaders.add(headerName, responseWrapper.getHeader(headerName));
    }
    String responseBody = IOUtils.toString(responseWrapper.getContentInputStream(), "UTF-8");
    System.out.println(responseBody);
    log.info("Response body {} ",responseBody);
    responseWrapper.copyBodyToResponse();
    }
user2478236
  • 691
  • 12
  • 32

2 Answers2

1

You never use response.getOutputStream() or response.getWriter() so no data is added to the response. That's why it is empty.

Your created entity

 ResponseEntity<JsonNode> responseEntity = new ResponseEntity<>(responseJson,responseHeaders,responseStatus);

is never used and never sent to response. Try e.g.

responseWrapper.getWriter().write("test");

and check the body after.

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • My rest api is returning return new ResponseEntity(statusResponse, HttpStatus.OK); is this because of this i am not able to get response. – user2478236 Jun 20 '17 at 08:00
  • As far as I can see it returns nothing - `void` – StanislavL Jun 20 '17 at 08:17
  • I am setting this object StatusResponse statusResponse = new StatusResponse(); statusResponse.setDataVersionNumber("4"); statusResponse.setModuleId("calc"); – user2478236 Jun 20 '17 at 08:31
  • I don't see the code posted. So your code is actually different and we should guess what is wrong with the code we don't see. It could be.... mmmm... difficult) – StanislavL Jun 20 '17 at 08:35
  • responseBody is empty. whereas the output of API call is.{ "moduleId": "calc", "dataversion": "4" } – user2478236 Jun 20 '17 at 08:55
0

How to read and copy the HTTP servlet response output stream content for logging

has your answer. The reason why getting your response output stream does not work is because the output stream gets written to and flushed regularly as you generate your output. This means that when you attempt to get it at the end, you just have an empty output. Alternatively, if you capture it at the beginning, that just means that your consumption of the outputstream denies the same consumption to your client. This is why you have to copy it as in the answer above.

Jeff Wang
  • 1,837
  • 1
  • 15
  • 29
  • this is talking about filters but I am using spring HandlerInterceptorAdapter . – user2478236 Jun 20 '17 at 08:03
  • The same reasoning applies. the key point here is that you can't access the outputstream that handles the response. you need to copy it. – Jeff Wang Jun 20 '17 at 08:08