Java Play!框架表单验证顺序

时间:2018-03-30 13:44:45

标签: java playframework

在游戏中! Framework 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字段 field1 field2 是否实际包含某些值,迫使我检查如果值为null则避免NullPointerExceptions。 我是否采用了错误的自定义验证方法,或者这是一个Play!意想不到的行为?

1 个答案:

答案 0 :(得分:0)

TLDR:RTFM; - )

在您的示例中,validate()方法在两个@Required约束之前未被评估:同时调用三个约束 - 因此基本上没有保证顺序将首先运行。 Play框架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方法。您也可以从(groups = {First.class})移除field2(因此默认情况下它也包含Default.class组),反之,添加{{1} } (groups = {First.class}) - 在这两种情况下,现在将同时评估两个字段 - 并且只有两个字段都成功,然后才会评估field1