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

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


Листинг 3.22. Компонент Customer со встроенными ограничениями и ограничением для электронной почты

>public class Customer {

>··@NotNull @Size(min = 2)

>··private String firstName;

>··private String lastName;

>··@Email

>··private String email;

>··private String phoneNumber;

>··@Past

>··private Date dateOfBirth;

>··private Address deliveryAddress;

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

>}

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

У Customer может быть ноль или один адрес доставки. Address — это компонент, включающий всю информацию, необходимую для доставки товара по указанному адресу: улица, город, штат, ZIP-код и страна. В листинге 3.23 показан компонент Address с ограничением @NotNull, налагаемым на важнейшие атрибуты (street1, city и zipcode), а также с ограничением @ZipCode, проверяющим валидность ZIP-кода (это ограничение будет разработано позже).


Листинг 3.23. Компонент Address со встроенными ограничениями и ограничением @ZipCode

>public class Address {

>··@NotNull

>··private String street1;

>··private String street2;

>··@NotNull

>··private String city;

>··private String state;

>··@NotNull @ZipCode

>··private String zipcode;

>··private String country;

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

>}

Написание ограничения @Email

Ограничение @Email не встроено в систему валидации компонентов, поэтому нам самим придется его разработать. Нам не понадобится класс реализации (@Constraint(validatedBy = {})), так как вполне работоспособным будет обычная ограничивающая аннотация с регулярным выражением (@Pattern) и заданным размером. В листинге 3.24 показана ограничивающая аннотация @Email.


Листинг 3.24. Ограничивающая аннотация электронной почты со встроенной агрегацией ограничений

>@Size(min = 7)

>@Pattern(regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\." 

>····+ "[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*" 

>····+ "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")

>@ReportAsSingleViolation

>@Constraint(validatedBy = {})

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

>@Retention(RUNTIME)

>public @interface Email {

>··String message() default " {org.agoncal.book.javaee7.chapter03.Email.message}";

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

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

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

>··@Retention(RUNTIME)

>··@interface List {

>····Email[] value();

>··}

>}

Обратите внимание: в листинге 3.24 сообщение об ошибке представляет собой ключ пакета, определяемый в файле META-INF/ValidationMessages.properties.

>org.agoncal.book.javaee7.chapter03.Email.message=invalid email address

Написание ограничения @ZipCode

Ограничение @ZipCode написать сложнее, чем @Email. ZIP-код имеет определенный формат (например, в США он состоит из пяти цифр), который не составляет труда проверить с помощью регулярного выражения. Но чтобы гарантировать, что ZIP-код не только синтаксически верен, но и валиден, необходимо прибегнуть к внешней службе, которая будет проверять, существует ли конкретный ZIP-код в базе данных. Именно поэтому ограничивающая аннотация ZipCode в листинге 3.25 требует класса реализации (ZipCodeValidator).


Листинг 3.25. Ограничивающая аннотация @ZipCode

>@Constraint(validatedBy = ZipCodeValidator.class)

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

>@Retention(RUNTIME)

>public @interface ZipCode {

>··String message() default "{org.agoncal.book.javaee7.chapter03.ZipCode.message}";

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

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

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

>··@Retention(RUNTIME)

>··@interface List {

>····ZipCode[] value();

>··}

>}

В листинге 3.26 показан класс реализации ограничивающей аннотации: ZipCodeValidator реализует интерфейс javax.validation.ConstraintValidator с обобщенным типом String. Метод isValid реализует алгоритм валидации, в рамках которого выполняется сопоставление с шаблоном регулярного выражения и происходит вызов внешнего сервиса: ZipCodeChecker. Код ZipCodeChecker здесь не показан, так как в данном случае он неважен. Но необходимо отметить, что он внедряется (@Inject) с квалификатором CDI (@USA, показан в листинге 3.27). Итак, здесь мы наблюдаем взаимодействие спецификаций CDI и Bean Validation.


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

>public class ZipCodeValidator implements ConstraintValidator {

>··@Inject @USA

>··private ZipCodeChecker checker;

>··private Pattern zipPattern = Pattern.compile("\\d{5}(-\\d{5})?");

>··public void initialize(ZipCode zipCode) {

>··}

>··public boolean isValid(String value, ConstraintValidatorContext context) {

>····if (value == null)

>······return true;

>····Matcher m = zipPattern.matcher(value);

>····if (!m.matches())

>····return false;

>····return checker.isZipCodeValid(value);

>··}

>}


Листинг 3.27. Квалификатор USACDI

>@Qualifier

>@Retention(RUNTIME)

>@Target({FIELD, TYPE, METHOD})

>public @interface USA {

>}


Примечание

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

Написание интеграционных тестов CustomerIT и AddressIT


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