Method Validation: "Bean Validation 1.1", JSR-349, Hibernate Validator Specifics
Hi All,
We are interested in method validation.
Currently the JSR 349: Bean Validation 1.1 is in the stage JSR Review Ballot.
We think it will specify some very useful extension to JSR 303: Bean Validation.
We are especially interested in the method validation part.
Method validation was also considered to be included in the Bean Validation API as defined by JSR 303, but it didn't become part of the 1.0 version. A basic draft is outlined in appendix C of the specification, and the implementation in Hibernate Validator is largely influenced by this draft.
Here's an example for method validation:
Code:
public class RentalStation {
@NotNull
public Car rentCar(@NotNull Customer customer, @NotNull @Future Date startDate, @Min(1) int durationInDays) {
//...
}
}
Today the Hibernate Validator already supports method validation. So, method validation can e.g. already be realized with Hibernate Validator and Spring AOP.
The Seam framework also included method validation using a custom annotation @AutoValidating.
We've seen that a little part like method validation is implemented in Spring MVC. Otherwise there's only bean validation (according JSR 303) implemented.
So, our question is: Are there any interests or plans by the Spring Community and SpringSource to have method validation in the Container? E.g. could all annotated beans with @Component (including sub-annotations like @Service etc.) automatically be method validated.
I hope this post could start a discussion.
In the meantime you can implement the method validation according to the Seam style with Spring AOP. See the code snippets below. Please note that this code is not intended to be used in production.
Code:
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoValidating {
}
Code:
@Aspect
@Component
public class MethodValidationInterceptor {
@Autowired
private ValidatorFactory validatorFactory;
@Around("@within(mypackage.AuoValidating))")
public Object validateMethodInvocation(ProceedingJoinPoint joinpoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinpoint.getSignature();
MethodValidator validator = validatorFactory.getValidator().unwrap(MethodValidator.class);
Set<MethodConstraintViolation<Object>> violations = validator.validateAllParameters(joinpoint.getThis(),
signature.getMethod(), joinpoint.getArgs());
if (!violations.isEmpty()) {
throw new MethodConstraintViolationException(violations);
}
Object result = joinpoint.proceed();
violations = validator.validateReturnValue(joinpoint.getTarget(), signature.getMethod(), result);
if (!violations.isEmpty()) {
throw new MethodConstraintViolationException(violations);
}
return result;
}
}
Best regards,
René