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

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

В следующем коде мы вызываем метод calculatePrice, передавая значение 1.2. В результате возникает нарушение ограничения, налагаемого на параметр: не выполняется условие @DecimalMin("1.4"). Для этого в коде сначала нужно создать объект java.lang.reflect.Method, нацеленный на метод calculatePrice с параметром типа Float. После этого он получает объект ExecutableValidator и вызывает validateParameters, передавая компонент, метод для вызова и значение параметра (здесь — 1.2). Затем метод удостоверяется в том, что никакие ограничения нарушены не были.

>CD cd = new CD("Kind of Blue", 12.5f);

>Method method = CD.class.getMethod("calculatePrice", Float.class);

>ExecutableValidator methodValidator = validator. forExecutables();

>Set> violations = methodValidator.validateParameters(cd, method,

>·················new Object[]{new Float(1.2)});

>assertEquals(1, violations.size());

Валидация групп

Группа определяет подмножество ограничений. Вместо валидации всех ограничений для данного компонента проверяется только нужное подмножество. При объявлении каждого ограничения указывается список групп, в которые входит это ограничение. Если явно не объявлена ни одна группа, то ограничение относится к группе Default. Что касается проверки, у всех валидационных методов есть параметр с переменным количеством аргументов, указывающий, сколько групп должно учитываться при выполнении валидации. Если этот параметр не задан, будет использоваться указанная по умолчанию валидационная группа (javax.validation.groups.Default). Если вместо Default указана другая группа, то Default не валидируется.

В листинге 3.21 все ограничения, за исключением применяемых с атрибутом description, относятся к группе Default. Описание (@NotNull @Size(min = 100, max = 5000)) требуется лишь в том случае, если диск должен быть упомянут в каталоге (группа PrintingCatalog). Итак, если мы создаем CD без заголовка, цены и описания, после чего проверяем лишь условия из группы Default, то будут нарушены всего два ограничения @NotNull, касающиеся title и price.

>CD cd = new CD();

>cd.setDescription("Best Jazz CD ever");

>Set> violations = validator.validate(cd, Default.class);

>assertEquals(2, violations.size());

Обратите внимание: в предыдущем коде при валидации явно упоминается группа Default, но это слово можно пропустить. Итак, следующий код идентичен предыдущему:

>Set> violations = validator. validate(cd);

С другой стороны, если бы мы решили проверить CD только для группы PrintingCatalog, то следующий код нарушал бы лишь ограничение, налагаемое на description, так как предоставляемое значение было бы слишком коротким:

>CD cd = new CD();

>cd.setDescription("Too short");

>Set> violations = validator.validate(cd, PrintingCatalog.class);

>assertEquals(1, violations.size());

Если бы вы хотели проверить компонент на соответствие обеим группам — Default и PrintingCatalog, то у вас было бы нарушено три ограничения (@NotNull для title и price, а также очень краткое описание):

>CD cd = new CD();

>cd.setDescription("Too short");

>Set> violations = validator.validate(cd, Default.class, PrintingCatalog.class);

>assertEquals(3, violations.size());

Все вместе

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

На рис. 3.2 показан класс Customer, имеющий адрес доставки (Address). Оба компонента снабжены встроенными ограничениями (@NotNull, @Size и @Past), которые применяются с их атрибутами. Но нам остается разработать еще два собственных ограничения:

• @Email — агрегированное ограничение, проверяющее правильность адреса электронной почты;

• @ZipCode — ограничение, проверяющее правильность почтового ZIP-кода (для США). В состав ограничения входит как аннотация, так и класс реализации (ZipCodeValidator). Обратите внимание: ZipCodeValidator внедряет вспомогательный класс ZipCodeChecker с аннотацией @Inject (и CDI-квалификатором @USA).

Классы, описанные на рис. 3.2, построены в соответствии со структурой каталогов Maven и должны находиться в следующих папках и файлах:

• src/main/java — папка для компонентов Customer, Address и ограничений ZipCode и Email;


Рис. 3.2. Все вместе


• src/main/resources — содержит файл beans.xml, поэтому мы можем использовать как CDI, так и файл ValidationMessages.properties для сообщений об ошибках, связанных с нарушением ограничений;

• src/test/java — папка для интеграционных тестов AddressIT и CustomerIT;

• pom.xml — объектная модель проекта Maven (POM), описывающая проект и его зависимости.

Написание компонента Customer

В приложении CD-Book Store клиент покупает товары, заказанные онлайн, и эти товары доставляются на его почтовый адрес. Для обеспечения такой доставки приложению нужна верная информация об имени клиента, адрес электронной почты и адрес доставки. Поскольку у нас есть дата рождения клиента, программа может ежегодно присылать ему соответствующее поздравление. В листинге 3.22 показан компонент Customer, включающий в себя несколько встроенных ограничений, налагаемых на атрибуты (firstname не может быть нулевым, а дата dateOfBirth должна относиться к прошлому). Здесь также есть ограничение @Email, которое мы разработаем. Код проверяет, является ли строка String валидным адресом электронной почты.


Рекомендуем почитать
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 так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.