Reputation: 11985
I am using Spring Boot + Spring Data JPA with Binding Results example. I have almost 100 controllers and for each Create/Update Request, we are doing below.
@PostMapping
public ResponseEntity<HttpStatus> saveStudent(@Valid @RequestBody StudentDto dto, BindingResult br){
if (br.hasErrors()) {
throw new InvalidRequestException("Wrong resource", br);
}
divisionService.saveStudent(dto);
return new ResponseEntity<>(HttpStatus.CREATED);
}
Is there any way if we can centralized this logic in one place ? Can we develop listeners for the same ?
if (br.hasErrors()) {
throw new InvalidRequestException("Wrong resource", br);
}
Upvotes: 2
Views: 2782
Reputation: 23226
You don't need a reference to the BindingResult
in your controller.
You would only need a reference to BindingResult
in the controller if you wanted to base some custom logic on whether or not it had errors e.g. redirect to a different view in a Rest API scenario.
Validation exceptions will be thrown either by the Java bean Validation framework (via
you @Valid
annotation) or by any Spring Validator
implementations applicable for the request.
In the case of the latter a MethodArgumentNotValidException will br thrown by the framework so you can simply create a ControllerAdvice (https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc) implementation which handles exceptions of this type and the BindingResult
can be fetched from this.
@ControllerAdvice
public class ValidationErrorHandlingAdvice {
/**
* Handler for {@link MethodArgumentNotValidException}s. These are triggered by
* Spring {@link Validator} implementations being invoked by the Spring MVC
* controllers and returning validation errors.
*
*
* @param ex The {@link MethodArgumentNotValidException} to be handled.
*
* @return {@link Map} keyed by field to which the error is bound and with the
* value of the field as a value.
*/
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public @ResponseBody ValidationErrors handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
Map<String, List<String>> errorMap = new TreeMap<>();
BindingResult result = ex.getBindingResult();
for (FieldError error : result.getFieldErrors()) {
if (!errorMap.containsKey(error.getField())) {
errorMap.put(error.getField(), new ArrayList<String>());
}
errorMap.get(error.getField()).add(error.getDefaultMessage());
}
return new ValidationErrors(errorMap);
}
private static class ValidationErrors {
private Map<String, List<String>> errors;
public ValidationErrors(Map<String, List<String>> errors) {
this.errors = errors;
}
@SuppressWarnings("unused")
public Map<String, List<String>> getErrors() {
return errors;
}
}
}
Upvotes: 1