··String message() default "{javax.validation.constraints.Pattern.message}";

··Class[] groups() default {};

··Class[] payload() default {};

··// Определяет несколько аннотаций @Pattern, применяемых к одному элементу

··@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})

··@Retention(RUNTIME)

··@interface List {

····Pattern[] value();

··}

}

Примечание

При разработке собственной ограничивающей аннотации следует добавить соответствующую ей аннотацию с множеством значений. Спецификация Bean Validation не требует этого строго, но настоятельно рекомендует определять внутренний интерфейс под названием List.

Ограничения на уровне класса

Выше мы рассмотрели различные способы разработки ограничения, которое применялось бы к атрибуту (или геттеру). Но вы также можете создать ограничение для целого класса. Идея заключается в том, чтобы выразить ограничение на основе нескольких свойств, которыми обладает заданный класс.

В листинге 3.11 показан класс для оформления заказа. Этот заказ товара следует определенному жизненному циклу бизнес-логики: создается в системе, оплачивается клиентом, а потом доставляется клиенту. Класс отслеживает все эти события, оперируя соответствующими датами: creationDate, paymentDate и deliveryDate. Аннотация @ChronologicalDates действует на уровне класса и проверяет, находятся ли эти даты в правильном хронологическом порядке.

Листинг 3.11. Ограничение, действующее на уровне класса и проверяющее верность хронологической последовательности дат

@ChronologicalDates

public class Order {

··private String orderId;

··private Double totalAmount;

··private Date creationDate;

··private Date paymentDate;

··private Date deliveryDate;

··private List orderLines;

··// Конструкторы, геттеры, сеттеры

}

В листинге 3.12 показана реализация ограничения @ChronologicalDates. Подобно тем ограничениям, что были рассмотрены выше, оно реализует интерфейс ConstraintValidator, обобщенный тип которого — Order. Метод isValid проверяет, находятся ли три даты в правильном хронологическом порядке, и если это так — возвращает true.

Листинг 3.12. Реализация ограничения ChronologicalDates, действующего на уровне класса

public class ChronologicalDatesValidator implements 

ConstraintValidator {

··@Override

··public void initialize(ChronologicalDates constraintAnnotation) {

··}

··@Override

··public boolean isValid(Order order, ConstraintValidatorContext context) {

····return order.getCreationDate(). getTime() < 

···········order.getPaymentDate(). getTime() && 

···········order.getPaymentDate(). getTime() <··

···········order.getDeliveryDate(). getTime();

··}

}

Ограничение на уровне метода

Ограничения, действующие на уровне методов, появились в спецификации Bean Validation 1.1. Существуют ограничения, объявляемые для методов, а также для конструкторов (геттеры не считаются ограниченными методами). Эти ограничения могут быть добавлены к параметрам метода (это будут «ограничения параметров») или к самому методу («ограничения возвращаемых значений»). Таким образом, спецификация Bean Validation может использоваться для описания и валидации соглашения, применяемого с заданным методом или конструктором. Так строится хорошо известный стиль «Программирование по соглашениям»:

• предусловия должны выполняться вызывающей стороной еще до вызова метода или конструктора;

• постусловия гарантированно выполняются для вызывающей стороны после возврата вызова, направленного к методу или конструктору.

Перейти на страницу:

Похожие книги