There is no special requirement for constraint-validators. As soon as the bean-validation module has been added to a project it's possible to use dependency injection in std. constraint-validators.
public class UserNameValidator implements ConstraintValidator<UserName, String>
{
@Inject
private UserService userService;
public void initialize(UserName userName)
{
}
public boolean isValid(String userName, ConstraintValidatorContext constraintValidatorContext)
{
return this.userService.validateUserName(userName);
}
}
|
You don't have to annotate such a ConstraintValidator with @Advanced. CODI will inject beans automatically, if you use the @Advanced qualifier for injection.
Via the @Advanced qualifier it's possible to inject the following BV artifacts in your beans:
CODI produces injectable (dependent) proxies which dynamically lookup the cached ValidatorFactory for creating new instances dynamically. So you don't have to care about correct caching of different bean-validation artifacts. E.g. every call of Validator#validate will automatically resolve the cached ValidatorFactory, creates a new Validator (because it isn't allowed to cache it) and call #validate on it. Everything a user has to do is:
public class DemoBean
{
@Inject
public DemoBean(@Advanced Validator validator)
{
this.validator = validator;
validate(); //uses the injected Validator - e.g.: validator.validate(this);
}
//...
}
|
In this case constructor injection is used, however, for sure it's possible to use the other injection types as well. The only part which is specific to CODI is the usage of the @Advanced qualifier and CODI will do the rest for you.
|
If you are using also the JSF module of CODI, you get the |
|
If you are using also the BV module of MyFaces ExtVal, ExtVal will use the |
Currently this class allows to implement custom ConstraintValidator s which can provide the invalid value in case of class level validation.
|
This feature is currently only available in combination with the JSF module. |
@Constraint(validatedBy = DifferentNameValidator.class)
@Target(TYPE)
@Retention(RUNTIME)
public @interface DifferentName
{
String message() default "The same name '{invalidValue}' isn't allowed.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@ApplicationScoped
public class DifferentNameValidator extends ClassLevelConstraintValidator<DifferentName, Person>
{
private static final long serialVersionUID = 3851988368625335444L;
@Inject
private ValidationService validationService;
private String invalidValue;
@Override
protected boolean isValidInstance(Person person, ConstraintValidatorContext constraintValidatorContext)
{
boolean result = this.validationService.isValid(person);
if(result)
{
this.invalidValue = null;
}
else
{
this.invalidValue = person.getFirstName();
}
return result;
}
@Override
protected Serializable getInvalidValue()
{
return this.invalidValue;
}
}
|