····if (port!= -1 && url.getPort()!= port) {
······context.disableDefaultConstraintViolation();
······context.buildConstraintViolationWithTemplate("Неверный
порт"). addConstraintViolation();
······return false;
····}
····return true;
··}
}
Группы
Когда компонент валидируется, в ходе проверки одновременно проверяются все его ограничения. Но что, если вам требуется частично валидировать компонент (проверить часть его ограничений) или управлять порядком валидации конкретных ограничений? Здесь нам пригодятся группы. Группы позволяют сформировать набор тех ограничений, которые будут проверяться в ходе валидации.
На уровне кода группа представляет собой обычный пустой интерфейс.
public interface Payment {}
На уровне бизнес-логики группа имеет определенное значение. Например, рабочая последовательность Payment (Платеж) подсказывает, что атрибуты, относящиеся к этой группе, будут валидироваться на этапе оплаты в рамках заказа товара. Чтобы применить эту группу с набором ограничений, нужно использовать атрибут groups и передать ему этот интерфейс:
@Past(groups = Payment.class)
private Date paymentDate;
Вы можете иметь столько групп, сколько требует ваша бизнес-логика, а также использовать то или иное ограничение с несколькими группами, поскольку атрибут groups может принимать целый массив групп:
@Past(groups = {Payment.class, Delivery.class})
private Date deliveryDate;
В каждой ограничивающей аннотации должен определяться элемент groups. Если ни одна группа не указана, то считается объявленной задаваемая по умолчанию группа javax.validation.groups.Default. Так, следующие ограничения являются эквивалентными и входят в состав группы Default:
@NotNull
private Long id;
@Past(groups = Default.class)
private Date creationDate;
Вновь рассмотрим случай с предшествующим использованием, в котором мы применяли аннотацию @ChronologicalDates, и задействуем в нем группы. В классе Order из листинга 3.18 содержится несколько дат, позволяющих отслеживать ход процесса заказа: creationDate, paymentDate и deliveryDate. Когда вы только создаете заказ на покупку, устанавливается атрибут creationDate, но не paymentDate и deliveryDate. Две эти даты нам потребуется валидировать позже, на другом этапе рабочего процесса, но не одновременно с creationDate. Применяя группы, можно валидировать creationDate одновременно с группой, проверяемой по умолчанию (поскольку для этой аннотации не указана никакая группа, для нее по умолчанию действует javax.validation.groups.Default). Атрибут paymentDate будет валидироваться на этапе Payment, а deliveryDate и @ChronologicalDates — на этапе Delivery.
@ChronologicalDates(groups = Delivery.class)
public class Order {
··@NotNull
··private Long id;
··@NotNull @Past
··private Date creationDate;
··private Double totalAmount;
··@NotNull(groups = Payment.class) @Past(groups = Payment.class)
··private Date paymentDate;
··@NotNull(groups = Delivery.class) @Past(groups = Delivery.class)
··private Date deliveryDate;
··private List
··// Конструкторы, геттеры, сеттеры
}
Как видите, в ходе валидации вам всего лишь следует явно указать, какие именно группы вы хотите проверить, и поставщик валидации из Bean Validation выполнит частичную проверку.
Дескрипторы развертывания
Как и большинство других технологий, входящих в состав Java EE 7, при валидации компонентов мы можем определять метаданные с помощью аннотаций (как это делалось выше) и с помощью XML. В Bean Validation у нас может быть несколько опциональных файлов, которые располагаются в каталоге META-INF. Первый файл, validation.xml, может применяться приложениями для уточнения некоторых особенностей поведения валидации компонентов (в частности, поведения действующего по умолчанию поставщика валидации компонентов, интерполятора сообщений, а также конкретных свойств). Кроме того, у вас может быть несколько файлов, описывающих объявления ограничений для ваших компонентов. Как и все дескрипторы развертывания в Java EE 7, XML переопределяет аннотации.