Home > database >  How can I get a body data from the request in an ExceptionHandler in Spring Boot?
How can I get a body data from the request in an ExceptionHandler in Spring Boot?

Time:04-13

I have a @RestControllerAdvice where I handle an Exception in Spring Boot. I would like to log an information that is sent through request body. How can I get this information from a spring WebRequest?

This is my sample exception handler.

@RestControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
        HttpHeaders headers, HttpStatus status, WebRequest request) {

    // I want to add something here that I could log an info that is in the request body.
    return super.handleMethodArgumentNotValid(ex, headers, status, request);
}

}

CodePudding user response:

Refer the code below — using the method logPostOrPutRequestBody we are able to read the InputStream from HttpServletRequest and log it to standard output.

@Component
public class LogRequestFilter implements Filter {

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

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {
    logPostOrPutRequestBody((HttpServletRequest) servletRequest);
    filterChain.doFilter(servletRequest, servletResponse);
  }

  private void logPostOrPutRequestBody(HttpServletRequest httpRequest) throws IOException {
    if(Arrays.asList("POST", "PUT").contains(httpRequest.getMethod())) {
      String characterEncoding = httpRequest.getCharacterEncoding();
      Charset charset = Charset.forName(characterEncoding);
      String bodyInStringFormat = readInputStreamInStringFormat(httpRequest.getInputStream(), charset);
      logger.info("Request body: {}", bodyInStringFormat);
    }
  }

  private String readInputStreamInStringFormat(InputStream stream, Charset charset) throws IOException {
    final int MAX_BODY_SIZE = 1024;
    final StringBuilder bodyStringBuilder = new StringBuilder();
    if (!stream.markSupported()) {
      stream = new BufferedInputStream(stream);
    }

    stream.mark(MAX_BODY_SIZE   1);
    final byte[] entity = new byte[MAX_BODY_SIZE   1];
    final int bytesRead = stream.read(entity);

    if (bytesRead != -1) {
      bodyStringBuilder.append(new String(entity, 0, Math.min(bytesRead, MAX_BODY_SIZE), charset));
      if (bytesRead > MAX_BODY_SIZE) {
        bodyStringBuilder.append("...");
      }
    }
    stream.reset();

    return bodyStringBuilder.toString();
  }

}

CodePudding user response:

RequestBody and ResponseBody can be read-only once so other ways to achieve the body in the exception handler Visit here

  • Related