To obtain a validator, you must first create a ValidatorFactory. If there is only one jsr303 implementation in your classpath, you can use:
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
to obtain the factory. If there are various implementations in the classpath, or you want to be sure you are using the Apache one, you can use:
ValidatorFactory avf = Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory();
You should not instantiate more than one factory, as factory creation is a costly process and the factory also acts as a constraint cache for the validators.
Once you have a ValidatorFactory, obtaining a validator just requires you to call ValidatorFactory#getValidator()
. The validator implementation is thread-safe, so you can choose to re-use a single instance of it in all your code or create validators on demand: both options are fine and should perform equally well.
Below is an example that will create a singleton ValidatorFactory and will let you obtain validators from it:
public enum MyValidatorFactory { SINGLE_INSTANCE { ValidatorFactory avf = Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory(); @Override public Validator getValidator() { return avf.getValidator(); } }; public abstract Validator getValidator(); }
Using the above class, obtaining a validator just requires you to call: MyValidatorFactory.SINGLE_INSTANCE.getValidator()
Using Spring
If you are using Spring, you can easily inject validators in your beans. Simply configure the factory in your applicationContext by adding:
<!-- Validator bean --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.apache.bval.jsr303.ApacheValidationProvider" /> </bean>
And Spring will be able to inject Validators and the ValidatorFactory in your beans.
Using Google Guice
Apache BVal provides the bval-guice
module that simplifies integration with Google Guice. That module has multiple purposes, such:
- bootstrap Apache BVal using Google Guice;
- obtain javax.validation.ConstraintValidator instances using the Google Guice Injector, to easily support the DI;
- easily inject the javax.validation.Validator reference into components that require it;
- easily intercept methods and validate method arguments.
First of all, users have to add the bval-guice
module in the classpath; Apache Maven users can easily include it just by adding the following dependency in the POM:
<dependency> <groupId>org.apache.bval</groupId> <artifactId>bval-guice</artifactId> <version>0.3-incubating</version> </dependency>
Let's have a look at the features:
Apache BVal bootstrapping
Simply, the org.apache.bval.guice.ValidationModule
is the Google Guice module that bootstraps Apache BVal; all users have to do is add this module when creating the Google Guice Injector:
import com.google.inject.Guice; import com.google.inject.Injector; import org.apache.bval.guice.ValidationModule; Injector injector = Guice.createInjector([...], new ValidationModule(), [...]);
obtain javax.validation.ConstraintValidator instances
Users can implement now javax.validation.ConstraintValidator classes that require Dependency Injection by Google Guice:
import javax.validation.ConstraintValidator; public class MyCustomValidator implements ConstraintValidator<MyAssert, MyType> { private final MyExternalService service; @Inject public MyCustomValidator(MyExternalService service) { this.service = service; } public void initialize(MyAssert annotation) { // do something } public boolean isValid(MyType value, ConstraintValidatorContext context) { return value == null || this.service.doSomething(value); } }
Don't forget to bind the MyExternalService
class in the Google Guice Bincer!!!
Inject the javax.validation.Validator reference
Clients can easily inject javax.validation.Validator
instances into their custom components just marking it using the Google Guice Inject annotation:
import javax.validation.Validator; public class MyValidatorClient { @Inject private Validator validator; public void setValidator(Validator validator) { this.validator = validator; } ... }
When obtaining MyValidatorClient
instances from the Injector, the javax.validation.Validator
will be automagically bound.
Intercept methods and validate method arguments
Taking advantage from the Apache BVal extension to validate method arguments, the bval-guice
comes with an AOP interceptor - automatically initialized in the org.apache.bval.guice.ValidationModule
- that makes easier the methods arguments validation.
All users have to do is annotate interested methods with org.apache.bval.guice.Validate
annotation, then annotate arguments with constraints, as follows below:
import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.apache.bval.guice.Validate; public class MyService { @Validate( groups = { MyGroup.class }, validateReturnedValue = true ) public Country insertCountry(@NotNull(groups = { MyGroup.class }) String name, @NotNull(groups = { MyGroup.class }) @Size(max = 2, groups = { MyGroup.class, MyOtherGroup.class }) String iso2Code, @NotNull(groups = { MyGroup.class }) @Size(max = 3, groups = { MyGroup.class, MyOtherGroup.class }) String iso3Code) { return ...; } }
The org.apache.bval.guice.Validate
supports 2 parameters:
groups
Class array, empty by default, that marks the groups have to be validated;validateReturnedValue
flag, false by default, that marks that if the returned object by the method execution has to be validated.
Using CDI
We recommend MyFaces CODI.