I've built a REST Service with Spring Boot. In one request method I'm validating the incoming request vs. an Object
that I have annotated for validation (@NotNull
etc.) using Hibernate Validator. The code for the REST endpoint looks like this:
@GetMapping(value = "/parameter-dates")
public ResponseEntity getParameterDates(ParameterDateRequest parameterDateRequest) {
Set<ConstraintViolation<ParameterDateRequest>> inputErrors = validator.validate(parameterDateRequest);
if (!inputErrors.isEmpty()) {
objectValidationErrorMessages = new ArrayList<>();
for (ConstraintViolation<ParameterDateRequest> constraintViolation : inputErrors) {
objectValidationErrorMessage = new ObjectValidationErrorMessage();
log.info("Error for user: " + loggedInUser.getUserEmail() +
" field: " + constraintViolation.getPropertyPath() + " with value: " + parameterDate.getParameterDateUnadjusted() +
" has error: " + constraintViolation.getMessage());
objectValidationErrorMessage.setFieldWithError(constraintViolation.getPropertyPath().toString());
objectValidationErrorMessage.setErrorMessage(constraintViolation.getMessage());
objectValidationErrorMessages.add(objectValidationErrorMessage);
}
return (new ResponseEntity(objectValidationErrorMessages, headers, HttpStatus.BAD_REQUEST));
}
//The rest of the code that is used when there is not validation errors
I would like to move the creation of the validation error messages to a metod of it's own like this:
public List<ObjectValidationErrorMessage> getErrorMessages(Class<?> clazz, Object model) {
List<ObjectValidationErrorMessage> objectValidationErrorMessages = new ArrayList<>();
Set<ConstraintViolation<?>> inputErrors = validator.validate(model);
if (!inputErrors.isEmpty()) {
for (ConstraintViolation<?> constraintViolation : inputErrors) {
objectValidationErrorMessage = new ObjectValidationErrorMessage();
objectValidationErrorMessage.setFieldWithError(constraintViolation.getPropertyPath().toString());
objectValidationErrorMessage.setErrorMessage(constraintViolation.getMessage());
objectValidationErrorMessages.add(objectValidationErrorMessage);
}
}
return objectValidationErrorMessages;
}
With the code as it is now I get the following error Unknow class: validateClass
for Set<ConstraintViolation<validatedClass>>
. How do I pass a Class
name, in this case ParameterDateRequest
as an argument to a method?
Update:
I manged to pass the Class
as Class<?> clazz
. I also realised that I need to pass the Object as an Object but I get this error:
validate (T, Class<?>...) in Validator cannot be applied
to (java.lang.Object)
reason: Incompatible equality constraint: ? and T
You can generify your method:
public <T> List<ObjectValidationErrorMessage> getErrorMessages(Class<T> clazz, T model) {
This will ensure that your Class<?>
token and your Object
have matching types.
Then pass the arguments as such:
validator.validate(model, clazz)
Note I could be misreading the error (I couldn't find the javadocs for the validator
), so it's also possible that validator
has a class-level generic (e.g. Validator<MyType>
). If that's the case, then the T
/Object
you pass to validator#validate
must match the type of the Validator
, but the second parameter seems to accept any classtype (Class<?>
). You also wouldn't need to generify the method as well, you would just have to match the type for the validator.