I was able to get the @Valid working and have validation responses return from my API, if a request body is not properly following the request model. However, it only works if I delete my Controller advice. With the AdviceController, I only get a blank BadRequest response. How can I maintain my global AdviceController and still get back the proper validation error messages. Also it would be nice to be able to customize the BadRequest error messages in the controller as well.
Controller:
@PostMapping(value = "/create", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<LinkTokenCreateResponse> createLinkToken(@Valid @RequestBody CreateLinkTokenReq createLinkTokenReq) throws Exception {
I have the required validation dependencies in the Pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
I have the error messages set to be included in responses in the Application.yaml:
server:
error:
include-message: always
include-binding-errors: always
I have the @Valid annotations in the Controller advice:
@ControllerAdvice
@Slf4j
public class AdviceConfig extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = {SQLException.class})
public ResponseStatusException handleSQLException(final SQLException e) {
return new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
I tried implementing a custom BadRequest error handler in the AdviceController, but I get an error from Spring:
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return errors;
}