親愛的Spring社區,使用JSR-303自定義驗證
我想實現如下:
- 我想有每個控制器(via
@InitBinder
) - 自定義驗證我想春天調用
validator.validate()
(所以not this way) - 我想用JSR-303
@Valid
標註爲 - 要驗證的bean(
RegistrationForm
)沒有任何每個字段的JSR-303註釋 - 我不想將驗證實現(如Hibernate)包含到classpath中;這將是無用的,從上面的語句
我基本上遵循的步驟中提到here:
- 我添加
javax.validation.validation-api:validation-api
作爲我的依賴 - 我用
<mvc:annotation-driven />
- 我記住我的模型
@Valid
:public String onRegistrationFormSubmitted(@ModelAttribute("registrationForm") @Valid RegistrationForm registrationForm, BindingResult result) ...
所以會發生什麼,是驗證API試圖找到任何實施和失敗:
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)
的出路是定義爲AnnotationDrivenBeanDefinitionParser
一個validator
屬性:
<bean name="validator" class="org.company.module.RegistrationFormValidator" />
<mvc:annotation-driven validator="validator" />
但這種做法意味着驗證將由ConfigurableWebBindingInitializer.initBinder()
設置給所有控制器。
我知道我試圖以一種特殊的方式使用框架,但是社區會說什麼,如果validator
屬性的特殊含義告訴驗證器不需要解析,例如,
<mvc:annotation-driven validator="manual" />
經過特殊處理:
--- 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) {
任何反饋意見表示歡迎。
P.S.從Spring Forum轉發。
謝謝,很好的解決方案。的確,如果'validation-api'不在classpath中,那麼' '不會嘗試通過工廠初始化實現。因此將使用特定於binder的驗證器。你是否通過控制器的'initBinder()'設置了驗證器? –
2012-04-23 10:06:52
謝謝!是的,按照文檔中建議的方式使用initBinder()。 – mhnagaoka 2012-04-25 01:39:59