Reputation: 3685
I have a class with validation annotations on my properties, like this one:
@NotNull(payload = INVALID_CATEGORY_DESCRIPTION.class)
@Size(min = 1, max = 255, payload = INVALID_CATEGORY_DESCRIPTION_LENGHT.class)
private String description;
Then I have a @ControllerAdvice to handle validation exceptions.
@ResponseStatus(BAD_REQUEST)
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> methodArgumentNotValidException(MethodArgumentNotValidException exception) {
When one or more validation annotation fail, the exception handler is triggered as expected.
In order to get the payload property from the annotations, I am iterating over the fields with validation errors, then over the annotations and only then comparing the annotation name with the FieldError code. With the annotation in hands I can access the payload.
I wonder if there is a more elegant way to get the payload or the annotation which triggered the exception, as there is for the message property (exception.getMessage()).
Upvotes: 9
Views: 3770
Reputation: 13733
To retrieve dynamic payload from MethodArgumentNotValidException:
List<ClassTypeDynamicPayload> allDynamicPayloadObjects = exception
.getBindingResult()
.getAllErrors()
.stream()
.map(validationFieldError -> validationFieldError.unwrap(ConstraintViolationImpl.class))
.map(constraintViolation -> constraintViolation.getDynamicPayload(ClassTypeDynamicPayload.class))
.collect(Collectors.toList())
To retrieve ConstraintViolation
(s) out of ConstraintViolationException use:
constraintViolationException.getConstraintViolations();
To get dynamic payload out of a ConstraintViolation
:
(ClassToMap) ((ConstraintViolationImpl) constraintViolation).getDynamicPayload(ClassToMap.class))
Upvotes: -1
Reputation: 11
I know this post is old but I think I might help others.
To get payload from MethodArgumentNotValidException
var constraintViolation = exception.getBindingResult()
.getAllErrors().get(0).unwrap(ConstraintViolation.class);
// Get dynamic payload
var payload = (Payload) ((ConstraintViolationImpl)
constraintViolation).getDynamicPayload(ValidationExceptionPayload.class);
Upvotes: 1
Reputation: 19119
Assuming your starting point is a ConstraintViolationException
you are getting the set of ConstraintViolation
instances via getConstraintViolations()
.
Each ConstraintViolation
then has a getConstraintDescriptor()
, which gives you metadata about the failing constraints. Once you have the ConstraintDescriptor
you just call getPayload()
.
Upvotes: 2