JSR-303 Annotations with AspectJ
First, configure your pom.xml
as explained here.
Then, include JSR-303 API and one of its reference implementations (for example, Hibernate Validator or Apache BVal):
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.CR3</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.bval</groupId> <artifactId>bval-jsr303</artifactId> <version>0.4</version> <scope>runtime</scope> </dependency>
Next, annotate method arguments:
import javax.validation.constraints.NotNull; public class Foo { public void doSomething(@NotNull String name) { // ... } }
That's it. Every time you call Foo.doSomething()
with NULL
a ConstraintViolationException
will be thrown.
Since 0.7.11 you can also annotate methods with @NotNull
in order to validate their output (an exception will be thrown if null
is returned by the method):
public class Foo { @NotNull public Data get() { // ... } }
Since 0.7.13 you can also annotate methods with @Valid
in order to validate their output:
public class Foo { @Valid public Data get() { // ... } }
And now a bit more complex example. Suppose you have a custom class Bar
that should be able to validate itself:
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import javax.validation.Payload; @Bar.Valid public class Bar { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = Bar.Validator.class) @Documented public @interface Valid { String message() default "invalid Bar"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } class Validator implements ConstraintValidator<Bar.Valid, Bar> { @Override public void initialize(Bar.Valid annotation) {} @Override public boolean isValid(Bar bar, ConstraintValidatorContext ctx) { if (!bar.name().matches("\\d+")) { ctx.buildConstraintViolationWithTemplate( String.format("invalid name %s", bar.name()) ).addPropertyNode("name").addConstraintViolation(); return false; } return true; } } public String name() { // return name of the object } }
Now objects of class Bar
can be validated every time they are used:
import javax.validation.Valid; public class Foo { public void doSomethingElse(@Valid Bar bar) { // ... } }
Every time method Foo.doSomethingElse()
is called bar
will be validated with Bar.Validator
.
At the moment we support only @NotNull
, @Pattern
, and @Valid
annotations. Mostly because method level validation is not supported in JSR-303 1.0.