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

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

buildConstraintViolationWithTemplateВозвращает ConstraintViolationBuilder, обеспечивающий построение пользовательского отчета о нарушении ограничения

Интерфейс ConstraintValidatorContext позволяет повторно определить заданное по умолчанию сообщение, связанное с ограничением. Метод buildConstraintViolationWithTemplate возвращает ConstraintViolationBuilder, опираясь на гибкий образец API, позволяющий создавать пользовательские отчеты о нарушениях. Следующий код добавляет к отчету информацию о новом нарушении ограничения:

>context.buildConstraintViolationWithTemplate("Invalid protocol")

>·······.addConstraintViolation();

Такая техника позволяет генерировать и создавать одно или несколько пользовательских сообщений-отчетов. Если рассмотреть пример с ограничением @URL из листинга 3.7, то мы увидим, что всему ограничению здесь соответствует лишь одно сообщение об ошибке (Malformed URL). Но у этого ограничения несколько атрибутов (protocol, host и port), и нам могут понадобиться специфичные сообщения для каждого из этих атрибутов, например: Invalid protocol (Недопустимый протокол) или Invalid host (Недопустимый хост).


Примечание

Интерфейс ConstraintViolation описывает нарушение ограничения. Он предоставляет контекст, в котором произошло нарушение, а также сообщение, описывающее это нарушение. Подробнее об этом читайте в разделе «Валидация ограничений» данной главы.


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


Листинг 3.17. Ограничение URL, использующее ConstraintValidatorContext для настройки сообщений об ошибках

>public class URLValidator implements ConstraintValidator {

>··private String protocol;

>··private String host;

>··private int port;

>··public void initialize(URL url) {

>····this.protocol = url.protocol();

>····this.host = url.host();

>····this.port = url.port();

>··}

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

>····if (value == null || value.length() == 0) {

>······return true;

>····}

>····java.net.URL url;

>····try {

>······url = new java.net.URL(value);

>····} catch (MalformedURLException e) {

>······return false;

>····}

>····if (protocol!= null && protocol.length() > 0 && 

>!url.getProtocol(). equals(protocol)) {

>······context.disableDefaultConstraintViolation();

>······context.buildConstraintViolationWithTemplate("Неверный 

>протокол"). addConstraintViolation();

>······return false;

>····}

>····if (host!= null && host.length() > 0 &&!url.getHost(). startsWith(host)) {

>······context.disableDefaultConstraintViolation();

>······context.buildConstraintViolationWithTemplate("Неверный 

>хост"). addConstraintViolation();

>······return false;

>····}

>····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.


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