Reputation: 499
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.
class vehicle {
@VehicleNameValidator
String vehicleName;
}
@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 { };
}
public class VehicleNameValidatorImpl implements ConstraintValidator<VehicleNameValidator, String[]> {
@Override
public boolean isValid(String vehicleName, ConstraintValidatorContext constraintValidatorContext) {
boolean isValid = logicmethod()//some logic here
return isValid;
}
}
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.
Upvotes: 6
Views: 10883
Reputation: 2533
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
Upvotes: 6
Reputation: 6226
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.
Upvotes: 0