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

Paulo Pedroso
  • 3,555
  • 2
  • 29
  • 34

3 Answers3

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

Hardy
  • 18,659
  • 3
  • 49
  • 65
  • 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. – Paulo Pedroso Apr 04 '16 at 13:36
  • Thanks. And `getPayload()` returns?? iterator of objects? classes? for parsing? casting? – e-info128 Aug 11 '20 at 06:50
0

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);
-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))
Gayan Weerakutti
  • 11,904
  • 2
  • 71
  • 68
  • The author said he [does not have access to a ConstraintViolationException](https://stackoverflow.com/questions/36343617/how-to-get-the-payload-property-from-bean-validation-annotation#comment60424726_36374457) – Tony D Feb 19 '21 at 13:42
  • This adds up to the answer made by @Hardy. Some might find it helpful. – Gayan Weerakutti Feb 19 '21 at 17:06