我使用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?
答案 0 :(得分:2)
好问题。我可以想到围绕你的问题的两种(不优雅的)方式。不幸的是,我认为Play的验证代码本身不支持这种情况:
如果您想强制执行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以获取有关注册验证方法的更多信息。
如果第一个选项听起来不吸引你,你可以创建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;
// ...
}