【问题标题】:How can a Spring Boot web app validate a form field that is required conditional on another field?Spring Boot Web 应用程序如何验证另一个字段所需的表单字段?
【发布时间】:2025-12-29 10:10:12
【问题描述】:

我有一个 Spring Boot Web 应用程序,其中我的表单支持 bean 的字段使用Bean Validation 注释进行注释(请参阅Baeldung's tutorialthe docs at spring.io)。例如,Customer bean 上的字段可能会这样注释:

@NotBlank
@Pattern(regexp="[ \\.A-Za-z-]*")
private String firstName;

@DateTimeFormat(pattern="M/d/yyyy")
@NotNull
@Past
private Date DOB;

我想知道的是:(如何)我可以实现一个查看多个字段的复杂验证吗?我的意思是,使用这个框架。例如,假设我有一个字段Country 和一个字段ZipCode,并且我希望ZipCode@NotBlank,当且仅当Country 等于"US",否则为可选。

在我的控制器中,使用@Valid 注释非常优雅地触发了验证,并且错误附加到BindingResult 对象。像这样:

@PostMapping("customer/{id}")
public String updateCustomer( @PathVariable("id") Integer id,
                              @Valid @ModelAttribute("form") CustomerForm form, 
                              BindingResult bindingResult ) {
    if (bindingResult.hasErrors()) {
        return "customerview";
    }
    customerService.updateCustomer(form);
    return "redirect:/customer/"+id;
}

我希望找到一种编写此条件验证器的方法,它也将由 @Valid 注释触发,并将其错误消息附加到 @ 中的 ZipCode 字段987654336@。理想情况下,我根本不需要更改控制器代码。

【问题讨论】:

    标签: java spring spring-boot validation bean-validation


    【解决方案1】:

    您可以获得创建自定义验证器类的帮助,以下链接可以帮助您: https://www.baeldung.com/spring-mvc-custom-validator#custom-validation

    【讨论】:

      【解决方案2】:

      对于这种东西,您需要使用跨字段验证。请尝试:

      创建注释:

      package foo.bar;
      
      @Target({ElementType.TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Constraint(validatedBy = {CustomerValidator.class})
      public @interface CustomerValid {
      
          String message() default "{foo.bar.CustomerValid.message}";
          Class<?>[] groups() default {};
          Class<? extends Payload>[] payload() default {};
      
      }
      

      创建自定义验证器:

      public class CustomerValidator implements ConstraintValidator<CustomerValid, Customer> {
      
          @Override
          public void initialize(CustomerValid constraint) {
          }
      
          @Override
          public boolean isValid(Customer customer, ConstraintValidatorContext context) {
              return !("US".equals(customer.getCountry() && "".equals(customer.getZipCode())));
          }
      }
      

      注释你的类:

      @CustomerValid
      public class Customer {
      // body
      }
      

      除了现有的字段验证器之外,还将处理此类验证。

      【讨论】:

        最近更新 更多