2016-07-15 9 views
2

私は日付を入力するためのSpring MVCフォームを持っています。入力はコントローラに送られ、標準のSpring MVC検証によって検証されます。@FutureとLocalDateのカスタムConstraintValidatorをSpringブートプロジェクトに追加する

モデル:

public class InvoiceForm { 
    @Future 
    private LocalDate invoicedate; 
} 

コントローラー:

public String postAdd(@Valid @ModelAttribute InvoiceForm invoiceForm, BindingResult result) { 
    .... 
} 

私は次のエラーを取得するフォーム提出時:

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.Future' validating type 'java.time.LocalDate'. Check configuration for 'invoicedate' 
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.throwExceptionForNullValidator(ConstraintTree.java:229) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorNoUnwrapping(ConstraintTree.java:310) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorInstanceForAutomaticUnwrapping(ConstraintTree.java:244) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:163) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:116) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:617) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:580) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:524) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:492) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:457) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:407) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:205) ~[hibernate-validator-5.2.4.Final.jar:5.2.4.Final] 
at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:108) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.validation.DataBinder.validate(DataBinder.java:866) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.validateIfApplicable(ModelAttributeMethodProcessor.java:164) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:111) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) ~[spring-webmvc-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at com.balticfinance.jwt.StatelessAuthenticationFilter.doFilter(StatelessAuthenticationFilter.java:46) ~[classes/:na] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:676) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91] 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91] 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.36.jar:8.0.36] 
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91] 

を、私はこのような場合のためにConstraintValidator自分を実施しました。しかし、どういうわけか、Spring Bootは検証のためにそれを拾いません。

@Component 
public class LocalDateFutureValidator implements ConstraintValidator<Future, LocalDate> { 

    @Override 
    public void initialize(Future future) { 
    } 

    @Override 
    public boolean isValid(LocalDate localDate, ConstraintValidatorContext constraintValidatorContext) { 
     LocalDate today = LocalDate.now(); 
     return localDate.isEqual(today) || localDate.isAfter(today); 
    } 
} 

私は自分の注釈を書き込んでそこのバリデーターを指定することができますが、よりクリーンで簡単な方法はありませんか?

+1

バリデーションがスプリングで管理されていないので、 '@ Component'はかなり役に立たないです。'@ Future'は、どのバリデータを使うべきかを指定しなければなりません。最近のバージョンのhibernateバリデーターを使用している場合、これはすぐに使用できるbtwでサポートされており、カスタムバリデーターはまったく必要ありません。 –

+1

ありがとう、https://hibernate.atlassian.net/browse/HV-874で判断する@Future with LocalDateは、hibernate-validator 5.2以降でサポートされるべきです。私は実際にはhibernate-validator 5.2.4.Finalを使用しています(自動的にspring-boot-startter-data-jpaによって推測されます)。 spring-boot-starter-parent 1.3.6.RELEASE –

+0

LocalDateのバリデータが削除されました。別のタイプを使用する必要がありますか? https://hibernate.atlassian.net/browse/HV-981 –

答えて

2

あなたがそうのように、META-INF/validation.xmlファイルに独自のバリデータを追加する必要があります。詳細については

<constraint-mappings 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd" 
    xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1"> 

    <constraint-definition annotation="javax.validation.constraints.Future"> 
     <validated-by include-existing-validators="true"> 
      <value>package.to.LocalDateFutureValidator</value> 
     </validated-by> 
    </constraint-definition> 
</constraint-mappings> 

refer to the official documentation.

+1

既存のバリデーターを除外する必要はありませんが、XMLを使用して新しいConstraintValidatorを追加するのが適切です。標準化されていないアプローチを使用したい場合は、ConstraintDefinitionContributorも参照できます。この場合、Java ServiceLoaderのアプローチを使用して、新しい制約バリデーターを追加できます。つまり、LocalDateの@Future実装が存在しない理由があります。 LocalDateにはタイムゾーン情報が含まれていないため、LocalDateが将来のものかどうかを定義することはできません。あなたのケースではOKかもしれませんが、 – Hardy

+0

これらは除外されていませんが、実際には含まれています:) –

+0

私は基本的に同じことをやろうとしているSpring Bootアプリを持っています。カスタムバリデータについてSpringにどのように伝えますか? validation.xmlファイル(Resourcesフォルダ内)にもかかわらず、UnexpectedTypeExceptionを取得し続ける –

0

私はMETA-INF/validation.xmlを使用すると、おそらくあることミロシュに同意するだろう最も簡単で簡単な方法ですが、もしあなたが本当に春の@Confgurationクラスに設定したいのであれば、それは可能です。

スプリングブートの美しさは、あなたのために多くの設定をするので、心配する必要はありません。しかし、これはあなた自身が特別な設定をしたいときにも問題を引き起こす可能性があります。

だから私はハーディが示唆(およびHibernateのドキュメントで参照される)ConstraintDefinitionContributorメカニズムを使用して@PastLocalDateためCustomerValidatorを追加しようとしている程度に設定昨日。その後、私はちょうど上で、怠け者だとちょうど私の構成で@Beanをインスタンス化

public class PastValidator implements ConstraintValidator<Past, LocalDate> { 

    @Override 
    public void initialize(Past constraintAnnotation) {} 

    @Override 
    public boolean isValid(LocalDate value, ConstraintValidatorContext context) { 
     return null != value && value.isBefore(LocalDate.now()); 
    } 
} 

単純なビットは、私の非常に特定の目的のためで構成検証を、行うために実装するクラスを作成することでしたSpringの自動設定クラスのひとつがHibernateバリデーターにそれを持ち込み、それをワイヤリングするだけです。これは、入手可能なドキュメント(またはその不足)とハーディーと他の人たちが言ったことを考えれば、かなり長引いていました。

org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTreeに例外が発生したため、デバッガを起動しましたが、@PastLocalDateのバリデータが見つかりませんでした。

ConstraintValidatorFactoryのタイプ階層を見ると、私はSpring MVCアプリケーションに2つの実装クラス、SpringConstraintValidatorFactorySpringWebConstraintValidatorFactoryがあり、正しいクラスのコンテキストからBeanを取得しようとしています。これは私のバリデータがSpringのBeanFactoryに登録されていなければならないと言いましたが、私はこれにブレークポイントを張ったときに私のPastValidatorのヒットを得ませんでした。これはHibernateがこれを要求する必要があるクラス。

これは理にかなっていました.Hepernateには、どこにもPastValidatorのインスタンスをSpringに要求する必要があることがどこにもありませんでした(ConstraintDefinitionContributor)。ドキュメントの例では、 http://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html_single/#section-constraint-definition-contributor のように、私はHibernateValidatorConfigurationにアクセスする必要があると示唆しています。そのため、Springがどこで設定を行っていたかを知る必要がありました。

ちょっと掘り下げた後、私は、春のLocalValidatorFactoryBeanクラスで、特にそのafterPropertiesSet()メソッドで起こっていたことを発見しました。そのjavadocをから:春はあなたのためにそれを行うにしよう、となるように本当の春のスタイルで、それは便利な拡張メソッドを提供する場合、基本的に

/* 
* This is the central class for {@code javax.validation} (JSR-303) setup in a Spring 
* application context: It bootstraps a {@code javax.validation.ValidationFactory} and 
* exposes it through the Spring {@link org.springframework.validation.Validator} interface 
* as well as through the JSR-303 {@link javax.validation.Validator} interface and the 
* {@link javax.validation.ValidatorFactory} interface itself. 
*/ 

、あなたが設定し、独自のバリデータを設定していない場合、これはありますあなたは自分の設定をしてから自分自身をミックスに追加することができます。

だから私のソリューションは、私は自分のConstraintDefinitionContributorインスタンスに登録することができるだろうように、ちょうどLocalValidatorFactoryBeanを拡張することでした:

import java.util.ArrayList; 
import java.util.List; 
import javax.validation.Configuration; 
import org.hibernate.validator.internal.engine.ConfigurationImpl; 
import org.hibernate.validator.spi.constraintdefinition.ConstraintDefinitionContributor; 
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 

public class ConstraintContributingValidatorFactoryBean extends LocalValidatorFactoryBean { 

    private List<ConstraintDefinitionContributor> contributors = new ArrayList<>(); 

    public void addConstraintDefinitionContributor(ConstraintDefinitionContributor contributor) { 
     contributors.add(contributor); 
    } 

    @Override 
    protected void postProcessConfiguration(Configuration<?> configuration) { 
     if(configuration instanceof ConfigurationImpl) { 
      ConfigurationImpl config = ConfigurationImpl.class.cast(configuration); 
      for(ConstraintDefinitionContributor contributor : contributors) 
       config.addConstraintDefinitionContributor(contributor); 
     } 
    } 
} 

をして、私の春の設定でこれをインスタンス化し、設定します。

@Bean 
    public ConstraintContributingValidatorFactoryBean validatorFactory() { 
     ConstraintContributingValidatorFactoryBean validatorFactory = new ConstraintContributingValidatorFactoryBean(); 
     validatorFactory.addConstraintDefinitionContributor(new ConstraintDefinitionContributor() { 
      @Override 
      public void collectConstraintDefinitions(ConstraintDefinitionBuilder builder) { 
        builder.constraint(Past.class) 
          .includeExistingValidators(true) 
          .validatedBy(PastValidator.class); 
      } 
     }); 
     return validatorFactory; 
    } 

完全性のために、PastValidator beanによってインスタンス化されたところもここにあります:

@Bean 
    public PastValidator pastValidator() { 
     return new PastValidator(); 
    } 

他の弾力-鮫

私はかなり大規模な春のMVCアプリケーションを持っているので、私はSpringConstraintValidatorFactorySpringWebConstraintValidatorFactoryの1の2つのインスタンスを見ていたというのが私のデバッグに気づきました。私は後者 が検証中に使用されていないことがわかったので、当分の間は無視しました。

それはあなたのConstraintContributingValidatorFactoryBeanを使用して、代わりに(申し訳ありませんが、私は「それは昨日これをしなかったが、couldnれているクラスを発見した他の ものを使用しないですることが可能ですので、春にはまた、使用するValidatorFactoryのどの実装を決定するための機構を備えています私は約2分だけ見て過ごしたが、今日はもう一度それを見つける)。

:あなたは非自明な方法 の任意の種類でのSpring MVCを使用している場合、チャンスはあなたがすでに WebMvcConfigurer場所あなたが Validator豆で明示的に配線することができを実装し、この一つとして独自の設定クラスを記述しなければならなかったです
public static class MvcConfigurer implements WebMvcConfigurer { 

    @Autowired 
    private ConstraintContributingValidatorFactoryBean validatorFactory; 

    @Override 
    public Validator getValidator() { 
     return validatorFactory; 
    } 

    // ... 
    // <snip>lots of other overridden methods</snip> 
    // ... 
} 

これが指摘したようにタイムゾーン情報がありませんので、あなたがLocalDate@Past検証を適用するには注意する必要があります

間違っています。ただし、LocalDateを使用している場合、すべてが同じタイムゾーンで実行されるか、意図的にタイムゾーンを無視するか、気にしなくてもよいので、これは問題ありません。

関連する問題