How to get the payload property from bean validation annotation
Asked Answered
D

3

9

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()).

Dulia answered 31/3, 2016 at 20:56 Comment(1)
Same problem here - how to get ConstraintViolationException instead of MethodArgumentNotValidException.Switzerland
T
2

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().

Tref answered 2/4, 2016 at 14:22 Comment(2)
Thank you @Hardy, the problem is the starting point is MethodArgumentNotValidException as it's not performing validations by code, it is relying in annotations.Dulia
Thanks. And getPayload() returns?? iterator of objects? classes? for parsing? casting?Longhand
B
1

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);
Bibliographer answered 26/9, 2021 at 13:30 Comment(1)
Thank you so much! Can not believe i could figure it out by myself!Jory
D
-1

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))
Dygall answered 28/10, 2020 at 9:49 Comment(2)
The author said he does not have access to a ConstraintViolationExceptionPeashooter
This adds up to the answer made by @Hardy. Some might find it helpful.Dygall

© 2022 - 2024 — McMap. All rights reserved.