I'm configuring a custom error handling in order to log every bad request to my API. In my scenario, is important to know the payload passed in the request so I can fix / test / reprocess it as needed.
I have built a simple @RestControllerAdvise
but I'm having a hard time on getting the request body from it:
@RestControllerAdvice
class ExceptionHandler {
companion object {
private val logger = getLogger()
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
fun badRequest(e: Exception, request: HttpServletRequest): Exception {
logger.error("Received a bad request with body: ${request.getBodyPlease()}", e) // Note getBodyPlease() is not a real method
return e
}
}
I have tried reading the InputStream
from the request but at this point it is already closed.
Another question suggests injecting a RequestContext
and setting it on Controller
. This wouldn't work in a Bad Request
scenario for it wouldn't execute the controller. Also it doesn't make much sense to set it in every controller.
Thanks in advance,
Edit
As @BeUndead suggested, I tried implementing a filter to wrap the request:
@Component
class RequestWrapperFilter : Filter {
override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
val reqWrapper = ContentCachingRequestWrapper(req as HttpServletRequest)
chain.doFilter(reqWrapper, res)
}
}
Then I'm trying to get body like request.reader.lines().collect(Collectors.joining())
.
When I try on the filter, with the ServletRequest
it works fine, I see the body. But when I try on the @ExceptionHandler
with the ContentCachingRequestWrapper
I get an empty string,