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

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

Затем вам придется управлять жизненным циклом ValidatorFactory и программно закрывать его:

>factory.close();

Если ваше приложение работает в контейнере Java EE, то контейнер должен предоставлять через JNDI следующие экземпляры:

• ValidatorFactory под java: comp/ValidatorFactory;

• Validator под java: comp/Validator.

Затем вы можете искать эти JNDI-имена и получать экземпляры Validator. Но вместо поиска экземпляров через JNDI вы можете запросить, чтобы они были внедрены с помощью аннотации @Resource:

>@Resource ValidatorFactory validatorFactory;

>@Resource Validator validator;

Если ваш контейнер использует CDI (а это происходит в Java EE 7 по умолчанию), то он должен допускать внедрение с помощью @Inject:

>@Inject ValidatorFactory;

>@Inject Validator;

В любом случае (как с @Resource, так и с @Inject) контейнер следит за жизненным циклом фабрики. Поэтому вам не придется вручную создавать или закрывать ValidatorFactory.

Валидация компонентов

Как только вы получите Validator программно или путем внедрения, можете использовать его методы как для валидации целого компонента, так и для работы с отдельно взятым свойством. В листинге 3.21 показан класс CD, в котором действуют ограничения, связанные со свойствами, параметрами методов и возвращаемым значением.


Листинг 3.21. Компонент с ограничениями, применяемыми со свойствами и методами

>public class CD {

>··@NotNull @Size(min = 4, max = 50)

>··private String title;

>··@NotNull

>··private Float price;

>··@NotNull(groups = PrintingCatalog.class)

>··@Size(min = 100, max = 5000, groups = PrintingCatalog.class)

>··private String description;

>··@Pattern(regexp = "[A-Z][a-z]{1,}")

>··private String musicCompany;

>··@Max(value = 5)

>··private Integer numberOfCDs;

>··private Float totalDuration;

>··@NotNull @DecimalMin("5.8")

>··public Float calculatePrice(@DecimalMin("1.4") Float rate) {

>····return price * rate;

>··}

>··@DecimalMin("9.99")

>··public Float calculateVAT() {

>····return price * 0.196f;

>··}

>}

Чтобы валидировать свойства целого компонента, мы просто должны создать экземпляр CD и вызвать метод Validator.validate(). Если экземпляр валиден, то возвращается пустое множество ConstraintViolation. В следующем коде показан валидный экземпляр CD (с заголовком и ценой), который и проверяется. После этого код удостоверяет, что множество ограничений действительно является пустым.

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

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

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

С другой стороны, следующий код вернет два объекта ConstraintViolation — один будет соответствовать заголовку, а другой — цене (оба они нарушают @NotNull):

>CD cd = new CD();

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

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

Валидация свойств

В предыдущих примерах валидируются свойства целого компонента. Но существует метод Validator.validateProperty(), позволяющий проверять конкретное именованное свойство заданного объекта.

В показанном ниже коде создается CD — объект, имеющий нулевой заголовок и нулевую цену; соответственно, такой компонент невалиден. Но, поскольку мы проверяем только свойство numberOfCDs, валидация проходит успешно и мы получаем пустое множество нарушений ограничений:

>CD cd = new CD();

>cd.setNumberOfCDs(2);

>Set> violations = validator.validateProperty(cd, "numberOfCDs");

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

С другой стороны, в следующем коде возникает нарушение ограничения, так как максимальное количество объектов CD должно равняться пяти, а не семи. Обратите внимание: мы используем API ConstraintViolation для проверки количества нарушений, интерполированного сообщения, возвращенного при нарушении, невалидного значения и шаблона сообщения:

>CD cd = new CD();

>cd.setNumberOfCDs(7);

>Set> violations = validator.validateProperty(cd, "numberOfCDs");

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

>assertEquals("must be less than or equal to 5", violations.iterator(). next(). getMessage());

>assertEquals(7, violations.iterator(). next(). getInvalidValue());

>assertEquals("{javax.validation.constraints.Max.message}",

>·············violations.iterator(). next(). getMessageTemplate());

Валидация значений

Пользуясь методом Validator.validateValue(), можно проверять, удастся ли успешно валидировать конкретное свойство указанного класса при наличии у свойства заданного значения. Этот метод удобен при опережающей валидации, так как не требует даже создавать экземпляр компонента, заполнять или обновлять его значения.

Следующий код не создает объект CD, а просто ссылается на атрибут numberOfCDs класса CD. Он передает значение и проверяет, является ли свойство валидным (количество CD не должно превышать пяти):

>Set> constr = validator.validateValue(CD.class, "numberOfCDs", 2);

>assertEquals(0, constr.size());

>Set> constr = validator.validateValue(CD.class, "numberOfCDs", 7);

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

Валидация методов

Методы для валидации параметров и возвращаемых значений методов и конструкторов вы найдете в интерфейсе javax.validation.ExecutableValidator. Метод Validator.forExecutables() возвращает этот ExecutableValidator, с которым вы можете вызывать validateParameters, validateReturnValue, validateConstructorParameters или validateConstructorReturnValue.


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