2012-02-13 25 views
6

Ho un modulo che contiene alcuni pulsanti radio e check-boxes. Ogni volta che l'utente seleziona/deseleziona un radio button o check-box, altri campi di input sono abilitati/disabilitati.
Desidero aggiungere la convalida solo per i campi abilitati quando l'utente invia il modulo. I campi che sono disabilitati al momento della presentazione non devono essere considerati per la convalida.Validazioni condizionali in primavera

Non voglio aggiungere questo nella validazione lato client. C'è un modo migliore/semplice per implementare la convalida condizionale in Spring 3.0 invece di aggiungere più if in validatore?

Grazie!

risposta

3

Quando i campi sono disabilitati vengono trasferiti al controller come null. Volevo aggiungere una convalida che permetta il campo null i.e disabilitato o il campo not blank cioè campo abilitato ma vuoto.
Così ho creato un'annotazione personalizzata NotBlankOrNull che consentirà null e stringhe non vuote, inoltre si occupa di spazi vuoti.
Qui è la mia annotazione di classe

@Documented 
@Constraint(validatedBy = { NotBlankOrNullValidator.class }) 
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) 
@Retention(RUNTIME) 
public @interface NotBlankOrNull { 
    String message() default "{org.hibernate.validator.constraints.NotBlankOrNull.message}"; 

    Class<?>[] groups() default { }; 

    Class<? extends Payload>[] payload() default { }; 
} 

Validator

public class NotBlankOrNullValidator implements ConstraintValidator<NotBlankOrNull, String> { 

    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { 
     if (s == null) { 
      return true; 
     } 
     return s.trim().length() > 0; 
    } 

    @Override 
    public void initialize(NotBlankOrNull constraint) { 

    } 
} 

Ho anche aggiornato ulteriori dettagli sulla mia site.

8

Se si utilizza la convalida JSR 303 Bean, è possibile utilizzare validation groups (groups) per questo.

Si supponga di avere questo input utente, contenente due sezioni. I due booleani indicano se le sezioni sono abilitate o disabilitate. (Naturalmente è possibile utilizzare le annotazioni più utile di @NotNull)

public class UserInput { 
    boolean sectionAEnabled; 
    boolean sectionBEnabled; 

    @NotNull(groups=SectionA.class) 
    String someSectionAInput; 

    @NotNull(groups=SectionA.class) 
    String someOtherSectionAInput; 

    @NotNull(groups=SectionB.class) 
    String someSectionBInput; 

    Getter and Setter 
} 

Hai bisogno di due interfacce per i gruppi. Funzionano solo come marker.

public interface SectionA{} 

public interface SectionB{} 

Since Spring 3.1 è possibile utilizzare l'annotazione Primavera @Validated (invece di @Validate) nel metodo di controllo per attivare la convalida:

@RequestMapping... 
public void controllerMethod(
     @Validated({SectionGroupA.class}) UserInput userInput, 
     BindingResult binding, ...){...} 

Prima Primavera 3.1 non c'era modo di specificare il gruppo di convalida che dovrebbe essere utilizzato per la convalida (perché non esiste e @Validate non ha un attributo di gruppo), quindi è necessario avviare la convalida per nd codice scritto: questo è un esempio su come attivare la convalida in dipendenza dalla sezione strega abilitata in Spring 3.0.

@RequestMapping... 
public void controllerMethod(UserInput userInput,...){ 

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
    Validator validator = factory.getValidator(); 

    List<Class<?>> groups = new ArrayList<Class<?>>(); 
    groups.add(javax.validation.groups.Default.class); //Always validate default 
    if (userInput.isSectionAEnabled) { 
    groups.add(SectionA.class); 
    } 
    if (userInput.isSectionBEnabled) { 
    groups.add(SectionB.class); 
    } 
    Set<ConstraintViolation<UserInput>> validationResult = 
    validator.validate(userInput, groups.toArray(new Class[0])); 

    if(validationResult.isEmpty()) { 
    ... 
    } else { 
    ... 
    } 
} 

(BTW: Per la soluzione Primavera 3.0, è anche possibile lasciare Primavera iniettare il validatore:

@Inject javax.validation.Validator validator 

<mvc:annotation-driven validator="validator"/> 

<bean id="validator" 
     class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
     <property name="validationMessageSource" ref="messageSource" /> 
</bean> 

)

+0

Sembra davvero un buon suggerimento. Mi chiedo solo come applicare questo ai campi presenti in DTO. Ho pochi campi che non sono presenti in bean/domain objecct ma presenti su DTO e voglio aggiungere anche convalide per loro. – xyz

+0

È possibile inserire questo anntoation javax.validation (NotNull, ...) su campi di classe molto, Entity DTO, ... Nell'esempio sopra, UserInput dovrebbe essere un DTO – Ralph