2011-07-26 15 views
10

¿Es posible usar tanto JSR-303 bean validation como traditional validation (una clase de validador única para el tipo) en Spring? Si es así, ¿qué configuración se requiere para configurar esto?¿Usando JSR-303 y Validación tradicional de frijol?

He intentado las instrucciones en el 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; 
    } 
} 

puedo conseguir esto para usar mi costumbre Validator o la validación de JSR-303, pero no ambos. Si tengo el initBinder presente como en el ejemplo, usa el Validator personalizado. Si lo elimino, se usa la validación de beans JSR-303. ¿Cómo puedo usar ambos?

Respuesta

1

Spring proporciona tres asas para la validación de bean.

clase 1.abstract AbstractPropertyValidationAnnotationHandler

clase 2.abstract AbstractMethodValidationAnnotationHandler

clase 3.abstract ClassValidationAnnotationHandler

En este ejemplo yo estoy poniendo en práctica la anotación personalizada CustomAnnotationHandle

@Target({ElementType.METHOD, ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
Class CustomAnnotationHandle extends Annotation{ 

    public abstract String value(); 

    } 

Implementar anotación personalizada para la validación de la propiedad, necesitamos extender AbstractPropertyValidationAnnotationHandler clase.

AbstractPropertyValidationAnnotationHandler proporciona método abstracto createValidationRule

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

Por lo tanto, la clase extendida debe proporcionar implementación de

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; 


} 

un resorte que proporciona la clase AnnotationBeanValidationConfigurationLoader Class.This se utiliza para la primavera propia anotación para la validación de frijol

La clase DefaultValidationAnnotationHandlerRegistry se utiliza como predeterminadoHandlerRegistry.Pero si tenemos que dar nuestra propia annotaion entonces

necesidad de ampliar AnnotationBeanValidationConfigurationLoader y fijamos nuestra handleregistry específica mediante el método setHandlerRegistry (nueva CustomPropertyAnnotationHandler());

Clase DefaultValidationAnnotationHandlerRegistry se utiliza para registrar la primavera propia anotación de frijol validation.It registro de frijol por

llamando al método registerPropertyHandler de SimpleValidationAnnotationHandlerRegistry class.So de nuestra anotación personalizada que necesitamos

CustomPropertyAnnotationHandler registro llamando al método registerPropertyHandler de SimpleValidationAnnotationHandlerRegistry clase

public class OurBeanSpecificValidationLoader extends AnnotationBeanValidationConfigurationLoader 
{ 

    public OurBeanSpecificValidationLoader() 
    { 
super(); 
     setHandlerRegistry(new OurSpecificAnnotationHandleRegistery()); 
    } 


} 

public class OurSpecificAnnotationHandleRegistery extends DefaultValidationAnnotationHandlerRegistry 
{ 

    public OurSpecificAnnotationHandleRegistery() 
    { 
     registerPropertyHandler(new CustomPropertyAnnotationHandler()); 
    } 
} 

así que usted tiene su costumbre anotación de frijol valiation.Eg

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

me di cuenta que es bastante viejo, pero tengo que esto funcione sin afectar demasiado a mi código

Cambio binder.setValidator(new DualEntryValidator());

a

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

Con setValidator() está reemplazando el validador JSR-303 con el suyo. Con addValidator(), se llama al validador JSR-303 y usted también.

usted necesita para asegurarse de que su validador no se superponga con sus JSR-303, @NotNull@Min, @Max, etc. anotaciones de lo contrario obtendrá mensajes de error duplicados agregaron.

+1

Esta debería ser la nueva respuesta aceptada. – shadowhorst

+0

Esto es lo que estoy usando, pero ahora necesito que el validador 'JSR-303' se llame * ANTES * mi' validador personalizado'. ¿Es posible lograr eso? Mi 'validador personalizado' ni siquiera debería invocarse si falla la validación 'JSR-303' básica (@NotNulls, etc) – Doug

+0

Mi validador personalizado arroja una excepción de puntero nulo porque el JSR-303 no entra antes, por lo tanto, nulo la validación no se realiza antes de que se active el validador personalizado – Doug

Cuestiones relacionadas