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.