Pass parameter from validate to custom validator in hibernate validator
Asked Answered
T

2

6

I'm trying to validate a bean using custom validator. But the validator needs info that is to be passed to it from the method where validate is invoked. Is there a way to do that?

I can't pass it in initialize as it is not available at the time of bean creation.

Bean to validate

class vehicle {
   @VehicleNameValidator
   String vehicleName;
}

Annotation

@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = VehicleNameValidatorImpl.class)
@Documented
public @interface VehicleNameValidator {
    String message() default "Invalid vehicle Name";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

custom validator

public class VehicleNameValidatorImpl implements ConstraintValidator<VehicleNameValidator, String[]> {

    @Override
    public boolean isValid(String vehicleName, ConstraintValidatorContext constraintValidatorContext) {
        boolean isValid = logicmethod()//some logic here
        return isValid;
    }
}

Main method

public static void main(String[] args) {
   String whatIwantToPass = runtimelogic(args);
   vehicle veh1 = new vehicle();
   Set<ConstraintViolation<vehicle>> constraintViolations = 
   validator.validate(veh1);
}

How to I pass variable "whatIwantToPass" from main method to VehicleNameValidatorImpl.

Tacye answered 25/6, 2019 at 17:48 Comment(0)
W
6

In case you are using Hibernate Validator you might want to take a look at constraint validator payload. In your case it would look somewhat like this:

In your validator impl you can access the payload:

public boolean isValid(String vehicleName, ConstraintValidatorContext constraintValidatorContext) {
    boolean isValid = false;
    if ( constraintValidatorContext instanceof HibernateConstraintValidatorContext ) {
        final String payload = constraintValidatorContext
                .unwrap( HibernateConstraintValidatorContext.class )
                .getConstraintValidatorPayload( String.class );
        // do whatever you need
        isValid = logicmethod()//some logic here
    }
    return isValid;
}

And the payload can be set either on the validator factory level or per validator like this:

ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
        .configure()
        .buildValidatorFactory();

String whatIwantToPass = runtimelogic( args );

Validator validator = validatorFactory.unwrap( HibernateValidatorFactory.class )
        .usingContext()
        .constraintValidatorPayload( whatIwantToPass )
        .getValidator();

// use the validator with the constraint validator payload 
vehicle veh1 = new vehicle();
Set<ConstraintViolation<vehicle>> constraintViolations = validator.validate( veh1 );

For more detailed info check this part of documentation - Passing a payload to the constraint validator

Wildee answered 27/6, 2019 at 8:6 Comment(0)
J
0

You could always use @Autowired or @Value annotations in the implementation of ConstraintValidator.I believe you could so something like this in your VehicleNameValidatorImpl.class

    public class VehicleNameValidatorImpl implements ConstraintValidator<VehicleNameValidator, String[]> {

        @Autowired
        LogicWrittenClass logicWrittenClass;

        @Override
        public boolean isValid(String[] roles, ConstraintValidatorContext constraintValidatorContext) {
            String whatIwantToPass  = logicWrittenClass.runtimelogic();
            boolean isValid = logicmethod()//some logic here
            return isValid;
        }
    }

But make sure that you use spring to create the validator bean otherwise the bean injection won't work as manually creating validator bean using valdiation factory (Hibernate Validator as reference implentation) does not inject dependencies into ConstraintValidator instances.

Johore answered 26/6, 2019 at 5:53 Comment(1)
The point is runtimelogic takes parameters that are available from main method args. How do I pass those?Tacye

© 2022 - 2024 — McMap. All rights reserved.