Spring中的条件验证

Spring中的条件验证,spring,validation,conditional,Spring,Validation,Conditional,我有一个表单,其中包含一些单选按钮和复选框。每当用户选择/取消选择单选按钮或复选框时,很少有其他输入字段被启用/禁用。 我只想为用户提交表单时启用的字段添加验证。提交时禁用的字段不应考虑进行验证 我不想在客户端验证中添加此项。是否有更好/更简单的方法在Spring 3.0中实现条件验证,而不是在validator中添加多个if 谢谢 如果您使用JSR303bean验证,那么您可以使用(groups)进行验证 假设您有此用户输入,包含两个部分。 两个布尔值指示节是启用还是禁用。(当然,您可以使用比

我有一个表单,其中包含一些
单选按钮和
复选框
。每当用户选择/取消选择
单选按钮
复选框
时,很少有其他输入字段被启用/禁用。
我只想为用户提交表单时启用的字段添加验证。提交时禁用的字段不应考虑进行验证

我不想在客户端验证中添加此项。是否有更好/更简单的方法在Spring 3.0中实现条件验证,而不是在validator中添加多个
if


谢谢

如果您使用JSR303bean验证,那么您可以使用(
groups
)进行验证

假设您有此用户输入,包含两个部分。 两个布尔值指示节是启用还是禁用。(当然,您可以使用比
@NotNull
更有用的注释)

组需要两个接口。它们只起标记作用

public interface SectionA{}

public interface SectionB{}
您可以在控制器方法中使用Spring
@Validated
注释(而不是
@Validate
)来触发验证:

@RequestMapping...
public void controllerMethod(
         @Validated({SectionGroupA.class}) UserInput userInput, 
         BindingResult binding, ...){...}
在Spring 3.1之前无法指定应用于验证的验证组(因为
@Validated
不存在且
@Validate
没有组属性),因此,您需要通过手写代码启动验证:这是一个如何触发验证的示例,依赖于Spring 3.0中启用的witch部分

@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 {
     ...
  }
}
@RequestMapping。。。
公共无效控件方法(UserInput UserInput,…){
ValidatorFactory=Validation.buildDefaultValidatorFactory();
Validator Validator=factory.getValidator();
列表>();
groups.add(javax.validation.groups.Default.class);//始终验证默认值
if(userInput.isSectionAEnabled){
添加组(第A节类);
}
如果(userInput.IsSectionBeEnabled){
添加组(第B节类);
}
设置验证结果=
validator.validate(userInput,groups.toArray(新类[0]);
if(validationResult.isEmpty()){
...
}否则{
...
}
}
(顺便说一句:对于Spring 3.0解决方案,也可以让Spring注入验证器:

@injectjavax.validation.Validator验证程序

)

当字段被禁用时,它们将作为
null
传输到控制器。我想添加一个验证,该验证将允许
null
即禁用字段或
非空
字段,即启用但为空字段。
因此,我创建了一个自定义注释
NotBlankOrNull
,它将允许
null
和非空字符串,它还处理空格。
这是我的注解

@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 { };
}
@已记录
@约束(validatedBy={NotBlankOrNullValidator.class})
@目标({方法,字段,注释类型,构造函数,参数})
@保留(运行时)
public@interface NotBlankOrNull{
String message()默认值“{org.hibernate.validator.constraints.NotBlankOrNull.message}”;
类[]组()默认值{};

类看起来是一个非常好的建议。只是想知道如何将其应用于DTO中的字段。我有几个字段不存在于bean/domain对象中,但存在于DTO中,我想为它们添加验证。您可以将这个javax.validation注释(NotNull,…)在上面的示例中,UserInput应该是DTO
@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>
@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 { };
}
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) {

    }
}