Controller method:
public Mission createMission(final @Valid @RequestBody Mission mission) {
//save..
return mission;
}
I want to enumerate all validation error messages as json and return.
I can do that with creating a new exception class, adding BindingResult in controller method param, throwing the new exception when binding result has error and handling the exception in @ControllerAdvice class.
if (bindingResult.hasErrors()) {
throw new InvalidRequestException("Fix input and try again", bindingResult);
}
But I want to avoid checking BindingResult in each controller method, rather handle globally. I could have done that if I could handle exception: org.springframework.web.bind.MethodArgumentNotValidException. But unfortunately Spring boot does not allow
@ExceptionHandler(MethodArgumentNotValidException.class)
it shows ambiguous exception handler, as the same exception is handled ResponseEntityExceptionHandler, and I can't override handleException as it is final. I tried overriding protected ResponseEntity handleMethodArgumentNotValid() by catching Exception.class, but that does not get called at all.
Is there any way to achieve this goal? it seems like lots of things for a simple task :(
You should create a class that use @ControllerAdvice
and extends ResponseEntityExceptionHandler
. Then you can override the method handleMethodArgumentNotValid
. You can use something like that:
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@Override
@ResponseStatus(HttpStatus.BAD_REQUEST)
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
final List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
Map <String, Set<String>> errorsMap = fieldErrors.stream().collect(
Collectors.groupingBy(FieldError::getField,
Collectors.mapping(FieldError::getDefaultMessage, Collectors.toSet())
)
);
return new ResponseEntity(errorsMap.isEmpty()? ex:errorsMap, headers, status);
}
}
If you don't want to extend to ResponseEntityExceptionHandler
, you need to annotate your GlobalExceptionHandler
to @ControllerAdvice
and @ResponseBody
.
Update:
Spring Boot created a new annotation @RestControllerAdvice
in combination of @ControllerAdvice
and @ResponseBody
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With