········<message>Title should not be null</message>
······</constraint>
····</field>
····<field name="price">
······<constraint annotation="javax.validation.constraints.NotNull"/>
······<constraint annotation="javax.validation.constraints.Min">
········<element name="value">2</element>
······</constraint>
····</field>
····<field name="description">
······<constraint annotation="javax.validation.constraints.Size">
········<element name="max">2000</element>
······</constraint>
····</field>
··</bean>
</constraint-mappings>
Файл constraints.xml из листинга 3.20 определяет метаданные для объявления ограничений, используемых с классом Book. Сначала он применяет ограничение @NotNull к атрибуту title и заново задает выводимое по умолчанию сообщение об ошибке («Название не может быть пустым»). К атрибуту price применяются два разных ограничения, его минимальное значение равно 2. Ситуация напоминает код из листинга 3.1, где метаданные определялись с помощью аннотаций.
Валидация ограничений
До сих пор мы плотно работали с ограничениями — определяли их, агрегировали, реализовывали наши собственные, настраивали сообщения об ошибках, возились с группами. Но без специальной валидационной среды исполнения проверка ограничений невозможна. Как и с большинством технологий Java EE 7, код в данном случае должен работать внутри контейнера или управляться поставщиком.
Ограничения можно применять к компонентам, атрибутам, геттерам, конструкторам, параметрам методов и возвращаемым значениям. Итак, валидация может выполняться для элементов всех этих типов. Можно валидировать компоненты, свойства, значения, методы и группы, а также задавать собственные ограничения для графа объектов. Чтобы все эти ограничения проверялись во время исполнения, вам потребуется валидационный API.
Валидационные API
Среда исполнения валидации использует небольшой набор API, которые позволяют ей проверять ограничения. Основной API — это интерфейс javax.validation.Validator. Он содержит соглашения для валидации объектов и графов объектов независимо от уровня, на котором этот интерфейс реализован (уровень представления, уровень бизнес-логики или бизнес-модели). При ошибке валидации возвращается набор интерфейсов javax.validation.ConstraintViolation. Он предоставляет контекст произошедшего нарушения, а также сообщение, описывающее нарушение.
Основной входной точкой для валидации является интерфейс Validator. Этот API позволяет проверять экземпляры компонентов, обходясь немногочисленными методами, перечисленными в табл. 3.4. Все эти методы объявляют каждое новое ограничение по одному и тому же образцу.
1. Устанавливается подходящая реализация ConstraintValidator, которая будет использоваться при определении данного ограничения (например, определяется ConstraintValidator для ограничения @Size, применяемого со строкой).
2. Выполняется метод isValid.
3. Если isValid возвращает true, программа переходит к следующему ограничению.
4. Если isValid возвращает false, поставщик валидации компонентов добавляет ConstraintViolation в список нарушений ограничений.
Метод | Описание |
---|---|
<T> Set<ConstraintViolation<T>>validate(T object, Class<?>… groups) | Валидирует все ограничения, применяемые с объектом |
<T> Set<ConstraintViolation<T>>validateProperty(T object, String propName, Class<?>… groups) | Валидирует все ограничения, касающиеся свойства |
<T> Set<ConstraintViolation<T>>validateValue(Class<T> beanType, String propName, Object value,Class<?>… groups) | Валидирует все ограничения, применяемые к свойству при заданном значении |
BeanDescriptor getConstraintsForClass(Class<?> clazz) | Возвращает объект дескриптора, описывающий ограничения компонента |
ExecutableValidator forExecutables() | Возвращает делегат для валидации параметров и возвращаемых значений у методов и конструкторов |
Если в ходе этой процедуры валидации происходит какая-либо неисправимая ошибка, то выдается исключение ValidationException. Это исключение может быть специализированным и может указывать на конкретные ситуации (недопустимое определение группы, недопустимое определение ограничения, недопустимое объявление ограничения).