Использование как JSR-303, так и традиционного Bean валидации?

Можно ли использовать JSR-303 bean валидация и традиционная проверка (один класс валидатора для типа) в Spring? Если да, какая конфигурация требуется для установки?

Я пробовал инструкции на 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. Как я могу использовать оба?

Ответ 1

Я сделал это, следуя инструкциям здесь:

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

См. раздел "Наслаждайтесь обоими мирами". В скором времени вы явно выполняете проверку JSR303 с помощью валидатора Spring, "присоединяя" результаты проверки 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 и т.д., иначе вы получите дублирующиеся сообщения об ошибках.

Ответ 3

Spring содержит три дескриптора для проверки bean.

1.абстрактный класс 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 Class. Этот класс используется для spring собственной аннотации для проверки bean.

Класс DefaultValidationAnnotationHandlerRegistry используется как defaultHandlerRegistry. Но если нам нужно предоставить нашу собственную аннотацию, мы

необходимо расширить AnnotationBeanValidationConfigurationLoader и установить нашу специфическую ручную работу с помощью метода setHandlerRegistry (новый CustomPropertyAnnotationHandler());

Класс DefaultValidationAnnotationHandlerRegistry используется для регистрации spring собственной аннотации для проверки bean. Регистр bean на

вызов метода registerPropertyHandler класса SimpleValidationAnnotationHandlerRegistry.So для нашей пользовательской аннотации нам нужно

зарегистрировать CustomPropertyAnnotationHandler, вызвав метод registerPropertyHandler класса SimpleValidationAnnotationHandlerRegistry

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;