【问题标题】:Java Play! Framework form validation order爪哇玩!框架表单验证顺序
【发布时间】:2018-03-30 13:44:44
【问题描述】:

在玩!框架 2.6 我已经实现了以下需要自定义验证的表单:

@Validate
public class MachineRegistrationForm implements Validatable<List<ValidationError>> {

    @Required
    private String field1;

    @Required
    private String field2;

    // other fields, getters and setters

    @Override
    public List<ValidationError> validate() {

        // validation on field1 and field2

    }
}

看起来 Play 执行了我的自定义验证之前检查 @Required 字段 field1field2 是否确实包含一些值,迫使我检查如果值为 null 以避免 NullPointerExceptions。 我是按照错误的方法进行自定义验证还是玩游戏!意外行为?

【问题讨论】:

    标签: java playframework


    【解决方案1】:

    TLDR:RTFM ;-)

    在您的示例中,validate() 方法未在两个 @Required 约束之前进行评估:三个约束同时调用 - 所以基本上没有保证先运行的顺序。这也记录在 Play Framework documentation

    还要注意,在本例中,validate 方法和@Constraints.Required 约束将同时被调用 - 因此无论@Constraints.Required 是否成功(反之亦然)都会调用 validate 方法。稍后您将学习如何介绍订单。

    如果您仔细阅读文档,您会发现"Defining the order of constraint groups" 部分:

    您可以按顺序验证组。这意味着将一个接一个地验证组 - 但只有在前一个组之前成功验证时才会验证下一个组。 (但是现在无法确定在组内验证约束的顺序......)

    为了让这个工作对你有用,让我们的团队很棒......

    public interface First { }
    

    ...和...

    public interface Second { }
    

    ...而且你必须很好地遵循组序列:

    import javax.validation.GroupSequence;
    import javax.validation.groups.Default;
    
    @GroupSequence({ Default.class, First.class, Second.class })
    public interface OrderedChecks { }
    

    然后您必须将组添加到您的约束中:

    @Validate(groups = {Second.class})
    public class MachineRegistrationForm implements Validatable<List<ValidationError>> {
    
        @Required // Default group is Default.class
        private String field1;
    
        @Required(groups = {First.class})
        private String field2;
    
        // other fields, getters and setters
    
        @Override
        public List<ValidationError> validate() {
    
            // validation on field1 and field2
    
        }
    }
    

    现在您可以使用定义的顺序触发验证:

    Form<MachineRegistrationForm> form = formFactory().form(MachineRegistrationForm.class, OrderedChecks.class).bindFromRequest();
    

    现在将首先检查field1,并且只有当它成功时才会检查field2,并且只有当它也成功时,才会检查validate 方法。您还可以从field2 中删除(groups = {First.class})(因此默认情况下它也有Default.class 组),反之,将(groups = {First.class}) 添加到field1 - 在两者中现在的情况下,这两个字段将同时被评估 - 只有当两者都成功时,validate 才会被评估。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多