If you want to do validation in the service layer, which is a good practice, Spring Boot supports it very well. Instead of using the @Valid annotation in the controller, you’ll need to do it in the service, as below:
Don’t miss the class level @Validated annotation.
So, how does it work?
Spring Boot auto configures a MethodValidationPostProcessor component, which validates all method parameters that are annotated with @Valid inside all components that are annotated with @Validated. It throws a ConstraintViolationException exception in case of errors.
Our job then becomes handling the exception and translating that to a suitable error response. While we've already discussed how to handle exceptions previous section, let's now discuss how to translate a ConstraintViolationException to a suitable response body.
ConstraintViolationException’s getConstraintViolations() method returns the errors as a set of ConstraintViolations. So, we should transform those ConstraintViolations into a simple structure and return that in the response.
A simple structure for returning validation errors to the client could look like this:
It's an array of error messages. Each error message has
These error messages can be structured as a simple class as below:
ConstraintViolation has the following attributes:
The propertyPath above is of the format methodName.objectName.fieldName. We won’t need the methodName prefix when sending it to the client. To strip it out, the code snippet below can be used:
So, in summary, the method below would convert a ConstraintViolation to a FieldError:
Using the above method, a set of ConstraintViolations can then be converted to a list of FieldErrors as below: