Paulo Pedroso
Paulo Pedroso

Reputation: 3685

How to get the payload property from bean validation annotation

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

Answers (3)

Gayan Weerakutti
Gayan Weerakutti

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

Azunite
Azunite

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

Hardy
Hardy

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

Related Questions