athom
athom

Reputation: 1608

Spring Bean validation with custom validator

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

Answers (1)

athom
athom

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

Related Questions