Using both JSR-303 and Traditional Bean Validation?

前端 未结 3 891
陌清茗
陌清茗 2020-12-31 13:59

Is it possible to use both JSR-303 bean validation and traditional validation (a single validator class for the type) in Spring? If so, what configuration is required to se

相关标签:
3条回答
  • 2020-12-31 14:07

    Spring provides three handle for bean validation.

    1.abstract class AbstractPropertyValidationAnnotationHandler

    2.abstract class AbstractMethodValidationAnnotationHandler

    3.abstract class ClassValidationAnnotationHandler

    In this example i am implementing custom annotation CustomAnnotationHandle

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

    To implement custom annotation for property validation we need to extend AbstractPropertyValidationAnnotationHandler Class.

    AbstractPropertyValidationAnnotationHandler provides createValidationRule abstract method

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

    So,the extended class must provide implementation of

    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 provides AnnotationBeanValidationConfigurationLoader Class.This class is used for spring own annotation for bean validation.

    DefaultValidationAnnotationHandlerRegistry class is used as defaultHandlerRegistry.But if we need to provide our own annotaion then we

    need to extend AnnotationBeanValidationConfigurationLoader and set our specific handleregistry via method setHandlerRegistry(new CustomPropertyAnnotationHandler());

    Class DefaultValidationAnnotationHandlerRegistry is used to register spring own annotation for bean validation.It register bean by

    calling registerPropertyHandler method of SimpleValidationAnnotationHandlerRegistry class.So for our custom annotation we need to

    register CustomPropertyAnnotationHandler by calling registerPropertyHandler method of SimpleValidationAnnotationHandlerRegistry class

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

    so you have your custom annotation for bean valiation.E.g

      @CustomAnnotationHandle(value = "test")
        private Object test;
    
    0 讨论(0)
  • 2020-12-31 14:13

    I've done that following the instructions here:

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

    See the "Enjoy both worlds" section. Shortly, you explicitly run a JSR303 validation from a Spring validator, "joining" the results of JSR303 validations based on annotations and your custom validation logic.

    0 讨论(0)
  • 2020-12-31 14:30

    I realise this is quite old, but I got this to work with minimal disturbance to my code

    Change binder.setValidator(new DualEntryValidator());

    to

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

    With setValidator() you're replacing the JSR-303 validator with your one. With addValidator(), the JSR-303 validator is called and so is yours.

    You need to make sure that your validator does not overlap with your JSR-303 @NotNull, @Min, @Max, etc. annotations otherwise you'll get duplicate error messages added.

    0 讨论(0)
提交回复
热议问题