使用JSR-303和传统Bean验证?

时间:2011-07-26 19:01:12

标签: spring spring-mvc bean-validation

是否可以在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验证。我如何使用两个

3 个答案:

答案 0 :(得分:9)

我按照这里的说明完成了这项工作:

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

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

答案 1 :(得分:8)

我意识到这已经很老了,但是我的工作对我的代码的干扰最小

更改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等注释不重叠,否则您将收到重复的错误消息。

答案 2 :(得分:1)

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

1.abstract class AbstractPropertyValidationAnnotationHandler

2.abstract class AbstractMethodValidationAnnotationHandler

3.abstract class 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类。该类用于bean自己的bean验证注释。

DefaultValidationAnnotationHandlerRegistry类用作defaultHandlerRegistry.But如果我们需要提供我们自己的注释,那么我们

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

类DefaultValidationAnnotationHandlerRegistry用于为bean验证注册spring自己的注释。它通过

注册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;