На заре
возникновения языка Java, не было стандартов для валидации данных - проверки
на правильность заполнения данных в моделях сущности и разработчики писали свои
валидаторы, что было не совсем удобно для сопровождения крупных проектов,
страдала переносимость кода. С некоторых пор появился стандарт JSR 303: Bean Validation, hibernate и некоторые другие вендоры решили реализовать его, мы
получили стандарт, которого стоит придерживаться при проверке данных. Для работы нам нужно подключить библиотеку hibernate-validator
все это я делаю через maven зависимости:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.0.Final</version>
</dependency>
Валидацию
в hibernate можно
провести двумя способами. Первый способ, представляет из себя простую последовательность действий, для
этого нужно. Первое описать поля сущностей специальными аннотациями,
которые будут накладывать на поля определенные ограничения. Второе запросить валидатор, у фабрики
классов. Третье заполнить сущность
данными. В четвертых вызвать у валидатора метод .validate() передав в качестве
параметра нашу сущность. Метод проверит
ограничения, которые были наложены на поля сущностей аннотациями и если были нарушены какие либо
правила, будет возвращен объект Set типа <ConstraintViolation>, в котором будут содержаться “ошибки” валидации.
Стоит упомянуть,
что ограничения накладываемые
аннотациями, не имеют ни чего общего с ограничениями баз данных, т. е. ограничения валидации не переносятся в
схему базы данных, если параметр hibernate.validator.apply_to_ddl выставлен в false, если выставить параметр в true, то все возможные
ограничения перенесутся в схему базы данных:
<property
name="hibernate.validator.apply_to_ddl">false</property>
Аннотация
|
Проверяемые типы данных
|
Применение
|
Метаданные переносятся ли в базу данных.
|
@AssertFalse
|
Boolean,
boolean
|
Проверяет,
имеет ли элемент значение false.
|
Нет.
|
@AssertTrue
|
Boolean,
boolean
|
Проверяет,
имеет ли элемент значение true.
|
Нет.
|
@DecimalMax(value=,
inclusive=)
|
BigDecimal, BigInteger, CharSequence, byte, short, int, long
и их примитивные типы.
|
Проверяет,
имеет ли элемент значение большее чем value, а если параметр inclusive=true,
больше или равно чем value.
|
Нет.
|
@DecimalMin(value=,
inclusive=)
|
BigDecimal, BigInteger, CharSequence, byte, short, int, long
и их примитивные типы.
|
Проверяет,
имеет ли элемент значение меньше чем value, а если параметр inclusive=true,
меньше или равно чем value.
|
Нет.
|
@Digits(integer=,
fraction=)
|
BigDecimal, BigInteger, CharSequence, byte, short, int, long
и их примитивные типы.
|
Проверяет,
имеет ли число количество знаков до запятой меньше или равно integer, и кол-во знаков
после запятой fraction
|
Создается число с точностью до запятой integer и после запятой fraction.
|
@Future
|
java.util.Date, java.util.Calendar;
|
Проверяет,
имеет ли дата значение большее, чем текущая
дата (системная).
|
Нет.
|
@Max(value=)
|
BigDecimal, BigInteger, CharSequence, byte, short, int, long
и их примитивные типы.
|
Проверяет,
имеет ли элемент значение меньше или равно чем value.
|
Создает
ограничение на поле таблицы.
|
@Min(value=)
|
BigDecimal, BigInteger, CharSequence, byte, short, int, long
и их примитивные типы.
|
Проверяет,
имеет ли элемент значение больше или равно чем value.
|
Создает
ограничение на поле таблицы.
|
@NotNull
|
Применим к
любым типам данных
|
Проверяет,
имеет ли элемент значение not
null.
|
Создает
ограничение на поле таблицы not
null.
|
@Null
|
Применим к
любым типам данных
|
Проверяет,
имеет ли элемент значение null.
|
Нет.
|
@Past
|
java.util.Date, java.util.Calendar;
|
Проверяет,
имеет ли дата значение меньше чем
текущая дата (системная).
|
Нет.
|
@Pattern(regex=,
flag=)
|
CharSequence
– Строки.
|
Проверяет,
строку на совпадение с регулярным выражением regex.
|
Нет.
|
@Size(min=,
max=)
|
CharSequence, Collection, Map и arrays
|
Проверяет
размерность элемента, т. е. количество
элементов должно быть в пределах минимума min и максимума max включительно.
|
Создается
ограничение,
|
@Valid
|
Любой не
примитивный тип.
|
Используется
для проверки ассоциированных объектов, коллекций, массивов данных.
|
Нет.
|
Рассмотрим
пример, создадим класс Per, с двумя полями пометим их аннотациями:
public class
Per implements Serializable{
@NotNull
private Long idP;
@Size(min = 3, message="Длина фамилии должна быть больше
трех")
private String name;
…
}
Создадим
две заведомо ошибочные ситуации в программе,
и отловим наши ошибки:
public class
Test_Validation {
public Test_Validation() {
ValidatorFactory vf =
Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
Per p = new Per();
p.setName("Vi");
Set<ConstraintViolation<Per>> constraintViolations =
validator.validate(p);
for (ConstraintViolation<Per>
cv : constraintViolations) {
System.out.format("Error
property: [%s], value: [%s], message: [%s]\n",
cv.getPropertyPath(),
cv.getInvalidValue(), cv.getMessage());
}
}
public static void main(String[] args) {
new Test_Validation();
}
}
Отловим две ошибки допущенные нами:
Error
property: [idP], value: [null], message: [may not be null]
Error property: [name], value: [Vi], message:
[Длина фамилии должна быть больше трех]
И так
перейдем ко второму способу, второй
способ, включает валидацию на уровне hibernate, для этого нужно в файле настроек hibernate.cfg.xml добавить 3 слушателя (Listener). Эти
слушатели будут перехватывать, и проверять правильность ввода данных, перед
вставкой (Insert),
перед изменениями (Update)
и перед удалением (Delete).
<event
type="pre-update">
<listener
class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
<event
type="pre-insert">
<listener
class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
<event
type="pre-delete">
<listener
class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
Комментариев нет:
Отправить комментарий