【问题标题】:Using both JSR-303 and Traditional Bean Validation?同时使用 JSR-303 和传统 Bean 验证?
【发布时间】:2011-07-26 19:01:11
【问题描述】:

是否可以在 Spring 中同时使用 JSR-303 bean validationtraditional validation(该类型的单个验证器类)?如果是这样,设置它需要什么配置?

我已经尝试了reference上的说明。

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.setValidator(new DualEntryValidator());
}

@RequestMapping(value="/dualEntry.htm", method = RequestMethod.POST)
public ModelAndView handlePost(@Valid DualEntryForm form, BindingResult result) {
    ModelAndView modelAndView = new ModelAndView("dualEntry", getCommonModel());

    if (!result.hasErrors()){
        //do logic
        return modelAndView;

    }else {
        modelAndView.addObject("dualEntryForm", form);
        return modelAndView;
    }
}

我可以让它使用我的自定义Validator JSR-303 验证,但不能同时使用两者。如果我在示例中存在 initBinder,它将使用自定义 Validator。如果我删除它,则使用 JSR-303 bean 验证。我如何同时使用

【问题讨论】:

    标签: spring spring-mvc bean-validation


    【解决方案1】:

    我已按照此处的说明进行操作:

    http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/

    请参阅“享受两个世界”部分。很快,您从 Spring 验证器显式运行 JSR303 验证,基于注释和自定义验证逻辑“加入”JSR303 验证的结果。

    【讨论】:

      【解决方案2】:

      我意识到这已经很老了,但我让它在对我的代码干扰最小的情况下工作

      更改binder.setValidator(new DualEntryValidator());

      @InitBinder
      protected void initBinder(WebDataBinder binder) {
          binder.addValidators(new DualEntryValidator());
      }
      

      使用setValidator(),您将用自己的验证器替换 JSR-303 验证器。使用addValidator(),将调用 JSR-303 验证器,您的验证器也是如此。

      您需要确保您的验证器不与您的 JSR-303 @NotNull@Min@Max 等注释重叠,否则您将收到重复的错误消息添加。

      【讨论】:

      • 这是我正在使用的,但我现在需要在我的custom validator 之前调用JSR-303 验证器之前。有可能实现吗?如果基本的JSR-303 验证失败(@NotNulls 等),我的custom validator 甚至不应该被调用
      • 我的自定义验证器抛出空指针异常,因为 JSR-303 没有提前启动,因此在触发自定义验证器之前没有进行空验证
      • Doug,如果没有代码示例,很难看出发生了什么。请使用示例代码和堆栈跟踪在 StackExchange 中发布一个新问题。
      【解决方案3】:

      Spring 为 bean 验证提供了三个句柄。

      1.抽象类AbstractPropertyValidationAnnotationHandler

      2.抽象类AbstractMethodValidationAnnotationHandler

      3.抽象类ClassValidationAnnotationHandler

      在这个例子中,我正在实现自定义注释 CustomAnnotationHandle

      @Target({ElementType.METHOD, ElementType.TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
       Class CustomAnnotationHandle extends  Annotation{
      
          public abstract String value();
      
         }
      

      要实现属性验证的自定义注释,我们需要扩展 AbstractPropertyValidationAnnotationHandler 类。

      AbstractPropertyValidationAnnotationHandler 提供 createValidationRule 抽象方法

      protected abstract AbstractValidationRule createValidationRule(Annotation annotation, Class class1, String s); 
      

      所以,扩展类必须提供实现

      protected abstract AbstractValidationRule createValidationRule(Annotation annotation, Class class1, String s) 
      
      public class CustomPropertyAnnotationHandler extends AbstractPropertyValidationAnnotationHandler
      {
      
          public CustomPropertyAnnotationHandler()
          {
              super(new Class[] {
                 XXX.XXX.PackageLevle.CustomAnnotationHandle // as it takes array of custom annotation ,so we can pass more than one 
              // overwriting abstract method
              protected  AbstractValidationRule createValidationRule(Annotation annotation, Class class1, String s){
                  CustomAnnotationHandle value = (CustomAnnotationHandle)annotation;
                  return TestValidationRule(value.getValue());
      
                  // as you can see it return AbstractValidationRule.So, we need a class to give our bean specific validation rule.In our case it is 
      
                  //TestValidationRule
              }
      
      
          }
      }
      
      public class TestValidationRule extends AbstractValidationRule
      {
      
          public TestValidationRule (String valuetest)
          {
           super();  
       this.valuetest = valuetest;
          }
      
      
      Private String valuetest;
      
      
      }
      

      Spring 提供了 AnnotationBeanValidationConfigurationLoader 类,该类用于spring自带的注解,用于bean的校验。

      DefaultValidationAnnotationHandlerRegistry 类用作 defaultHandlerRegistry。但是如果我们需要提供自己的注解,那么我们

      需要扩展 AnnotationBeanValidationConfigurationLoader 并通过方法设置我们具体的handleregistry setHandlerRegistry(new CustomPropertyAnnotationHandler());

      Class DefaultValidationAnnotationHandlerRegistry用于注册spring自己的注解进行bean验证。它通过注册bean

      调用SimpleValidationAnnotationHandlerRegistry类的registerPropertyHandler方法。所以对于我们的自定义注解我们需要

      调用SimpleValidationAnnotationHandlerRegistry类的registerPropertyHandler方法注册CustomPropertyAnnotationHandler

      public class OurBeanSpecificValidationLoader extends AnnotationBeanValidationConfigurationLoader
      {
      
          public OurBeanSpecificValidationLoader ()
          {
      super();
              setHandlerRegistry(new OurSpecificAnnotationHandleRegistery ());
          }
      
      
      }
      
      public class OurSpecificAnnotationHandleRegistery extends DefaultValidationAnnotationHandlerRegistry
      {
      
          public OurSpecificAnnotationHandleRegistery ()
          {
              registerPropertyHandler(new CustomPropertyAnnotationHandler() );
          }
      }
      

      这样你就有了 bean valiation.E.g 的自定义注释

        @CustomAnnotationHandle(value = "test")
          private Object test;
      

      【讨论】:

        猜你喜欢
        • 2015-01-10
        • 1970-01-01
        • 2012-05-12
        • 1970-01-01
        • 2013-11-23
        • 2011-10-29
        • 2012-02-08
        • 1970-01-01
        • 2011-07-24
        相关资源
        最近更新 更多