Spring 中的条件验证

发布于 2025-01-04 19:00:55 字数 275 浏览 0 评论 0原文

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

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

谢谢!

I have a form which contain some radio button and check-boxes. Whenever user selects/deselects a radio button or check-box few other input fields are enabled/disabled.
I want to add validation only for fields which are enabled when user submits the form. Fields which are disabled at the time of submission should not be considered for validation.

I don't want to add this in client side validation.Is there any better /easy way to implement conditional validation in Spring 3.0 instead of adding multiple if in validator ?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无法回应 2025-01-11 19:00:55

如果您使用 JSR 303 Bean 验证,则可以使用 验证组)。

假设您有此用户输入,其中包含两个部分。
两个布尔值指示这些部分是启用还是禁用。 (当然,您可以使用比 @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
}

您需要两个组接口。它们仅用作标记。

public interface SectionA{}

public interface SectionB{}

自 Spring 3.1 您可以在控制器方法中使用 Spring @Validated 注解(而不是 @Validate)来触发验证:

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

在 Spring 3.1 之前没有办法指定应该用于验证的验证组(因为@Validated不存在且@Validate没有group属性),所以需要启动验证手工编写代码:这是一个如何根据 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 {
     ...
  }
}

(顺便说一句:对于 Spring 3.0 解决方案,也可以让 Spring 注入验证器:

@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>

If you use JSR 303 Bean validation then you can use validation groups (groups) for this.

Assume you have this user input, containing two sections.
The two booleans indicating if the sections are enabled or disabled. (Of course you can use more useful annotations than @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
}

You need two Interfaces for the groups. They work only as marker.

public interface SectionA{}

public interface SectionB{}

Since Spring 3.1 you can use the Spring @Validated annotation (instead of @Validate) in your controller method to trigger the validation:

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

Before Spring 3.1 there was no way to specify the validation group that should been used for validation (because @Validated does not exist and @Validate does not have a group attribute), so you need to start the validation by hand written code: This an an example how to trigger the validation in dependence to witch section is enabled 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: For the Spring 3.0 solution, it is also possible to let Spring inject the validator:

@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>

)

陌上青苔 2025-01-11 19:00:55

当字段被禁用时,它们将作为 null 传输到控制器。我想添加一个验证,允许 null (即禁用字段)或 not Blank 字段(即启用但为空字段)。
因此,我创建了一个自定义注释 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 { };
}

验证器类,

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) {

    }
} 

我还在我的 网站上更新了更多详细信息

When fields are disabled they are transferred to controller as null. I wanted to add a validation which will allow either null i.e disabled field or not blank field i.e. enabled but empty field.
So I created a custom annotation NotBlankOrNull which will allow null and non empty strings also it takes care of blank spaces.
Here is my Annotation

@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 class

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) {

    }
} 

I have also updated more details on my site.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文