Изучаем Java EE 7 - [37]

Шрифт
Интервал

• @Constraint(validatedBy = NotNullValidator.class) — указывает класс (в случае агрегации ограничений — нуль либо список классов), в котором инкапсулирован валидационный алгоритм;

• @Documented — определяет, будет эта аннотация включена в Javadoc или нет. Опциональная метааннотация.

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

• message — обеспечивает для аннотации возможность возвращения интернационализированного сообщения об ошибке, выдаваемого в том случае, если ограничение недопустимо. По умолчанию данный атрибут равен ключу;

• groups — используется для контроля за порядком, в котором интерпретируются ограничения, либо для выполнения частичной валидации;

• payload — применяется для ассоциирования метаинформации с ограничением.

Если ваше ограничение определяет все обязательные метааннотации и ограничения, можете добавить любой интересующий вас конкретный параметр. Например, ограничение, проверяющее длину строки, может использовать атрибут length для указания максимальной длины.


Реализация ограничений

Ограничение определяется комбинацией самой аннотации и нуля или более классов реализации. Классы реализации указываются элементом validatedBy в @Constraint (как показано в листинге 3.2). Листинг 3.3 демонстрирует класс реализации для аннотации @NotNull. Как видите, он реализует интерфейс ConstraintValidator и использует дженерики для передачи имени аннотации (NotNull) и типа, к которому применяется аннотация (в данном случае это Object).


Листинг 3.3. Реализация ограничения NotNull

>public class NotNullValidator implements ConstraintValidator {

>··public void initialize(NotNull parameters) {

>··}

>··public boolean isValid(Object object, ConstraintValidatorContext context) {

>····return object!= null;

>··}

>}

Интерфейс ConstraintValidator определяет два метода, которые обязательны для реализации конкретными классами.

• initialize — вызывается поставщиком валидации компонентов еще до применения какого-либо ограничения. Именно здесь мы обычно инициализируем любые параметры ограничения, если они имеются.

• isValid — здесь реализуется валидационный алгоритм. Метод интерпретируется поставщиком валидации компонентов всякий раз, когда проверяется конкретное значение. Метод возвращает false, если значение является недопустимым, в противном случае — true. Объект ConstraintValidatorContext несет информацию и операции, доступные в том контексте, к которому применяется ограничение.

Реализация ограничения выполняет валидацию заданной аннотации для указанного типа. В листинге 3.3 ограничение @NotNull типизируется к Object (это означает, что данное ограничение может использоваться с любым типом данных). Но у вас может быть и такая ограничивающая аннотация, которая применяет различные алгоритмы валидации в зависимости от того, об обработке какого типа данных идет речь. Например, вы можете проверять максимальное количество символов для String, максимальное количество знаков для BigDecimal или максимальное количество элементов для Collection. Обратите внимание: в следующей аннотации у нас несколько реализаций одной и той же аннотации (@Size), но она используется с разными типами данных (String, BigDecimal и Collection):

>public class SizeValidatorForString·····implements·····{…}

>public class SizeValidatorForBigDecimal implements {…}

>public class SizeValidatorForCollection implements> {…}


Применение ограничения

Когда у вас есть аннотация и ее реализация, вы можете применять ограничение с элементом заданного типа (атрибут, конструктор, параметр, возвращаемое значение, компонент, интерфейс или аннотация). Это решение, которое разработчик принимает на этапе проектирования и реализует с помощью метааннотации @Target(ElementType.*) (см. листинг 3.2). Существуют следующие типы:

• FIELD — для ограниченных атрибутов;

• METHOD — для ограниченных геттеров и возвращаемых значений ограниченных методов;

• CONSTRUCTOR — для возвращаемых значений ограниченных конструкторов;

• PARAMETER — для параметров ограниченных методов и конструкторов;

• TYPE — для ограниченных компонентов, интерфейсов и суперклассов;

• ANNOTATION_TYPE — для ограничений, состоящих из других ограничений.

Как видите, ограничивающие аннотации могут применяться с большинством типов элементов, определяемых в Java. Только статические поля и статические методы не могут проверяться валидацией компонентов. В листинге 3.4 показан класс Order, где ограничивающие аннотации применяются к самому классу, атрибутам, конструктору и бизнес-методу.


Листинг 3.4. Объект, использующий ограничения с элементами нескольких типов

>@ChronologicalDates

>public class Order {

>··@NotNull @Pattern(regexp = "[C,D,M][A-Z][0–9]*")

>··private String orderId;

>··private Date creationDate;

>··@Min(1)

>··private Double totalAmount;

>··private Date paymentDate;

>··private Date deliveryDate;

>··private List orderLines;

>··public Order() {

>··}

>··public Order(@Past Date creationDate) {

>····this.creationDate = creationDate;


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.