Как ограничить проверку в мастере воспроизведения?
Я использую Play Framework 2.2.1, и я реализовал свой собственный мастер из этого примера. Но у меня есть проблема с проверкой, потому что пользователь определяет больше "адресов" и в разных шагах моего мастера.
Вот мой класс 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
// ...
}
Вот мой класс Address:
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;
// ...
}
Проверка на шаге 1 завершается ошибкой, потому что атрибуты "улица" и "номер" являются пустыми / пустыми в "invoiceAddress". Вот фрагмент из моего контроллера:
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 ответ
Хороший вопрос. Я могу придумать два (не элегантных) пути решения вашей проблемы. К сожалению, я не думаю, что код проверки 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;
// ...
}
Проверьте документацию для получения дополнительной информации о регистрации метода проверки.
Вариант 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;
// ...
}