Как ограничить проверку в мастере воспроизведения?

Я использую 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;

    // ...
}
Другие вопросы по тегам