嵌套验证组、Spring、JSR 303

6

我正在尝试在我的Spring应用程序中进行嵌套验证。

public class Parent{

   public interface MyGroup{}

   @NotNull(groups = MyGroup.class)
   private Child child;

   // getters and setters omited

}

public class Child{

   public interface OptionalGroup {}

   @NotBlank(groups = OptionalGroup.class)
   private String aField;

}

我已经查看了javax.validation包中的@Valid,但它不支持分组。我还检查了Spring的@Validated注释,但无法将其应用于字段。

我想做类似于:

public class Parent{

   public interface MyGroup{}

   @NotNull(groups = MyGroup.class)
   @CascadeValidate(groups = MyGroup.class, cascadeGroups = OptionalGroup.class) 
   // 'groups' correspond to parent group and 'cascadeGroups' to a group that needs to be apply to the Child field.

   private Child child;

}

然后我可以实现任何我想要的:

@Inject SmartValidator validator;

public void validationMethod(Parent parent, boolean condition) throws ValidationException {
   if(condition){
      MapBindingResult errors= new MapBindingResult(new HashMap<>(), target.getClass().getSimpleName());

      validator.validate(parent, errors, Parent.MyGroup.class); // validate all constraints associated to MyGroup

      if(errors.hasErrors()) throw new ValidationException(errors); // A custom exception
   }

}

有什么想法如何做到这一点吗?非常感谢。

@Validated 用于指定在验证时要使用哪些组。因此,当从 Web 提交表单时,只验证指定的那些组。您可以指定0个或多个组以用于验证。 - M. Deinum
是的,我不能用这个注释实现我想要的功能,但我提到它是因为它的哲学思想。我的问题与表单或网络无关,只涉及级联验证组。 - LG_
这与Spring无关,而是与bean验证的工作方式有关。Spring没有对此进行任何添加。 - M. Deinum
好的。我正在寻找一些不同的东西。我想要能够在我的父对象的字段上写@CascadeValid(groups = MyParentGroup.class, subgroups = MyChildGroup.class)。然后,使用此注释,我希望我的验证器能够检测到它并在我的子对象上启动嵌套验证。 - LG_
1个回答

8

我终于找到了解决方法。实际上,我误解了 @Valid 的作用。

关键在于为父级和子级属性声明相同的分组。

解决方案:

public class Parent{

   public interface MyGroup{}

   @NotNull(groups = MyGroup.class)
   @Valid // This annotation will launch nested validation
   private Child child;

   // getters and setters omited

}

public class Child{

   @NotBlank(groups = Parent.MyGroup.class) // Declare same group
   private String aField;

}

在这种情况下,当我执行以下操作时:
 @Inject SmartValidator validator;

public void validationMethod(Parent parent, boolean condition) throws ValidationException {
   if(condition){
      MapBindingResult errors= new MapBindingResult(new HashMap<>(), target.getClass().getSimpleName());

      // validate all constraints associated to MyGroup (even in my nested objects)
      validator.validate(parent, errors, Parent.MyGroup.class); 

      if(errors.hasErrors()) throw new ValidationException(errors); // A custom exception
   }

}

如果在我的子字段'aField'中检测到验证错误,则第一个相关的验证错误代码(参见FieldError.codes)将是'NotBlank.Parent.afield'。

我应该更好地查看@Valid文档。


非常好的回答。谢谢。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接