Reputation: 1608
I have implemented a custom size validation in order to add "errorCode" to a validation error.
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { StringLengthValidator.class })
public @interface StringLength {
String message() default "Size must be between {min} and {max}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
long min() default 0L;
long max();
String errorCode() default "";
}
I have annotated a field in my DTO with the following:
@StringLength(min = 5, max = 400, errorCode = "1000001")
In the @RestControllerAdvice
I added the following:
@ExceptionHandler({WebExchangeBindException.class})
Mono<ResponseEntity<...>> webExchangeBindException(WebExchangeBindException exception, ServerHttpRequest request) {
...
}
How can I get the errorCode of the original annotation, in order to add that to my response?
I have found that exception.getFieldError().getArguments()
contains an array with the the value I want wrapped in a SpringValidatorAdapter.ResolvableAttribute
but I do not know how to use it.
Upvotes: 1
Views: 930
Reputation: 1608
The best I could come up with was to inject a javax.validation.Validator
into the @RestControllerAdvice
Then use the following @ExceptionHandler
to get the "errorCode" value of the validation annotation.
@ExceptionHandler({WebExchangeBindException.class})
Mono<ResponseEntity<...>> webExchangeBindException(WebExchangeBindException exception, ServerHttpRequest request) {
Set<ConstraintViolation<Object>> violations = validator.validate(exception.getTarget());
violations.stream()
.findFirst()
.ifPresent(violation -> /*Assign error here */ ... violation.getConstraintDescriptor().getAttributes().get("errorCode"));
return ...;
}
This works, but I feel there should be a better way to do this.
Upvotes: 1