如何在Play向导中限制验证?

时间:2014-02-19 13:58:50

标签: java validation playframework-2.0 wizard

我使用Play Framework 2.2.1并且我从这个sample实现了我自己的向导。但是我的验证有问题,因为用户在我的向导中定义了更多“地址”-es和不同的步骤。

这是我的Person类:

import javax.validation.Valid;

public class Person {

    @Valid
    private Address permanentAddress;    // restrict the validation to the Step1

    @Valid
    private Address invoiceAddress;      // restrict the validation to the Step2

    // ...
}

这是我的地址类:

import play.data.validation.Constraints.Required;

public class Address {

    @Required(groups = { Step1.class, Step2.class })
    private String street;

    @Required(groups = { Step1.class, Step2.class })
    private String number;

    // ...
}

Step1中的验证现在失败,因为“invoiceAddress”中的属性“street”和“number”为空/空。这是我的控制器的片段:

private static Result handleStep1Submission() {
    Form<Person> filledForm = form(Person.class, Step1.class).bindFromRequest();

    if (filledForm.hasErrors()) {
         // this now fails because "invoiceAddress.street" and
         // "invoiceAddress.number" are null/empty
    } else {
         // ...
}

在这种情况下如何将验证限制为Step1或Step2?

1 个答案:

答案 0 :(得分:2)

好问题。我可以想到围绕你的问题的两种(不优雅的)方式。不幸的是,我认为Play的验证代码本身不支持这种情况:

选项1:临时验证

如果您想强制执行Play不会开箱即用的一些漂亮的验证规则(例如跨字段验证),这是推荐的方法。如果您在表单类中定义validate方法,Play将通过反射找到它并在处理完所有验证注释后调用它:

public class Person {

    // New field, gets populated by a hidden field in your HTML form
    private int step;

    private Address permanentAddress;    // restrict the validation to the Step1

    private Address invoiceAddress;      // restrict the validation to the Step2

    // ...

    public String validate() {

        if (step == 1) {
            // manually validate permanentAddress
        }

        if (step == 2) {
            // manually validate invoiceAddress
        }
    }
}

由于所有验证现在都是临时的而非注释驱动的,因此您可以从Address中删除注释:

public class Address {

    private String street;

    private String number;

    // ...
}

检查documentation以获取有关注册验证方法的更多信息。

选项2:子类地址

如果第一个选项听起来不吸引你,你可以创建Address个子类(可能在过程中提取出一个接口):

public interface Address {

    public String getStreet();

    public String getNumber();

    // ...
}


import play.data.validation.Constraints.Required;

public class PermanentAddress implements Address {

    @Required(groups = {Step1.class})
    private String street;

    @Required(groups = {Step1.class})
    private String number;

    // ...
}


import play.data.validation.Constraints.Required;

public class InvoiceAddress implements Address {

    @Required(groups = {Step2.class})
    private String street;

    @Required(groups = {Step2.class})
    private String number;

    // ...
}


import javax.validation.Valid;

public class Person {

    @Valid
    private PermanentAddress permanentAddress;

    @Valid
    private InvoiceAddress invoiceAddress;

    // ...
}