How to get the @RequestBody in an @ExceptionHandler (Spring REST)
Accepted answer creates a new POJO to pass things around, but the same behaviour can be achieved without creating additional objects by reusing the http request.
Example code for Controller mapping:
public ResponseEntity savePerson(@RequestBody Person person, WebRequest webRequest) {
webRequest.setAttribute("person", person, RequestAttributes.SCOPE_REQUEST);
And later in the ExceptionHandler class / method you can use:
@ExceptionHandler(Exception.class)
public ResponseEntity exceptionHandling(WebRequest request,Exception thrown) {
Person person = (Person) request.getAttribute("person", RequestAttributes.SCOPE_REQUEST);
You can reference the request body object to a request-scoped bean. And then inject that request-scoped bean in your exception handler to retrieve the request body (or other request-context beans that you wish to reference).
// @Component
// @Scope("request")
@ManagedBean
@RequestScope
public class RequestContext {
// fields, getters, and setters for request-scoped beans
}
@RestController
@RequestMapping("/api/v1/persons")
public class PersonController {
@Inject
private RequestContext requestContext;
@Inject
private PersonService personService;
@PostMapping
public Person savePerson(@RequestBody Person person) throws PersonServiceException {
requestContext.setRequestBody(person);
return personService.save(person);
}
}
@ControllerAdvice
public class ExceptionMapper {
@Inject
private RequestContext requestContext;
@ExceptionHandler(PersonServiceException.class)
protected ResponseEntity<?> onPersonServiceException(PersonServiceException exception) {
Object requestBody = requestContext.getRequestBody();
// ...
return responseEntity;
}
}