Dear Spring community,
What I am trying to implement is the following:
@InitBinder)validator.validate() (so not this way)@Valid annotation for thatRegistrationForm) does not have any per-field JSR-303 annotationsI basically follow the steps mentioned here:
javax.validation.validation-api:validation-api as my dependency<mvc:annotation-driven />@Valid:
public String onRegistrationFormSubmitted(@ModelAttribute("registrationForm") @Valid RegistrationForm registrationForm, BindingResult result) ...So what happens, is that validation API tries to locate any implementation and fails:
Caused by: javax.validation.ValidationException: Unable to find a default provider
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:264)
at org.springframework.validation.beanvalidation.LocalValidatorFactoryBean.afterPropertiesSet(LocalValidatorFactoryBean.java:183)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
The way out is to define a validator property for AnnotationDrivenBeanDefinitionParser:
<bean name="validator" class="org.company.module.RegistrationFormValidator" />
<mvc:annotation-driven validator="validator" />
but this approach means that the validator will be set to all controllers by ConfigurableWebBindingInitializer.initBinder().
I understand that I am trying to use the framework in a special way, but what the community will say, if there is a special meaning for validator property which tells that validator does not need to be resolved, e.g.
<mvc:annotation-driven validator="manual" />
with special treatment:
--- AnnotationDrivenBeanDefinitionParser.java.orig 2011-06-30 14:33:10.287577300 +0200
+++ AnnotationDrivenBeanDefinitionParser.java 2011-06-30 14:34:27.897449000 +0200
@@ -152,6 +152,10 @@
private RuntimeBeanReference getValidator(Element element, Object source, ParserContext parserContext) {
if (element.hasAttribute("validator")) {
+ if ("manual".equals(element.getAttribute("validator"))) {
+ return null;
+ }
+
return new RuntimeBeanReference(element.getAttribute("validator"));
}
else if (jsr303Present) {
Any feedback is welcomed.
P.S. Repost from Spring Forum.
This is also a repost of my answer/workaround on the above mentioned forum. Anyway I think it might help having it here as well.
The only workaround I found was to implement my own @Valid annotation, once Spring (at least in 3.1.1.RELEASE code base) only checks the method argument annotation's simple name (please look into the org.springframework.web.method.annotation.ModelAttributeMethodProcessor class below). This way, I don't need to add javax.validation.validation-api:validation-api to my project's dependencies and I stop getting the infamous javax.validation.ValidationException: Unable to find a default provider.
/**
* Validate the model attribute if applicable.
* <p>The default implementation checks for {@code @javax.validation.Valid}.
* @param binder the DataBinder to be used
* @param parameter the method parameter
*/
protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
Annotation[] annotations = parameter.getParameterAnnotations();
for (Annotation annot : annotations) {
if (annot.annotationType().getSimpleName().startsWith("Valid")) {
Object hints = AnnotationUtils.getValue(annot);
binder.validate(hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
}
}
}
Why you don't want to include Hibernate Validator? Ever JSR specification have some implementations, you can not work with the specification without any implementation (or provider).
Can you imagine working with JDBC without any JDBC driver? Working with JPA without a provider? Working with Servlets without any container?
It's just the same, Hibernate Validator is the reference implementation of JSR-303, I'm not aware of any other implementation, but if you don't like Hibernate Validator, just go for another implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With