How to register custom Spring validator and have automatic dependency injection?

162 Views Asked by At

When working with ConstraintValidators, we just need to define the class and constraint and Spring is able to detect the validators and instantiate them automatically, injecting any beans we ask for in the constructor.

How do I add my custom Spring Validators (https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/Validator.html) in the same manner?

2

There are 2 best solutions below

0
Ananta On BEST ANSWER

You have to let the controller to know which validator will validate your request. I use following code to find supported validators:

@ControllerAdvice
@AllArgsConstructor
public class ControllerAdvisor {

    private final List<Validator> validators;

    @InitBinder
    public void initBinder(@NonNull final WebDataBinder binder) {
        final Object request= binder.getTarget();
        if (request== null) {
            return;
        }
        this.validators.stream()
            .filter(validator -> validator.supports(request.getClass()))
            .forEach(binder::addValidators);
    }

}

Note that you have to create those validators as beans. Therefore, you should annotate those validators with @Component. Hope this help you.

2
mamJavad On

in your controller you need to create an API that has a RequestBody and @valid annotation for example

public ResponseEntity<String> foo(@RequestBody @Valid Bar bar){
//do sth
}

then create a class that implements Validator interface provided by spring validator. you have to implement 2 methods -> support and validate in support method you have to setting the class that you need to validate : it means before the running your API method spring see valid annotation and check their implementations of Validator interface if support class and your requestBody class are same then running validate method in custom validator . support method sample :

@Override
    public boolean supports(Class<?> clazz) {
        return Bar.class.equals(clazz);
    }

and in your validate method you have 2 inputs -> object and error . first cast your object to Bar object then start your validation of Bar class and if something is bad use error.reject and fill error object with messages . if error!=null then spring will return 400 (bad request) to client with your custom messages.