Статьи

Использование Hibnate Bean Validator в Java SE

На главной странице Bean Validation говорится, что «Bean Validation — это спецификация Java, которая… работает в Java SE, но интегрирована в Java EE (6 и 7)». Этот пост демонстрирует использование эталонной реализации Java Bean Validation ( Hibernate Validator ) вне контейнера Java EE. Примеры в этом посте основаны на Hibernate Validator 5.1.3 Final , который можно скачать по адресу http://hibernate.org/validator/downloads .

« Начало работы с Hibernate Validator » гласит, что Hibernate Validator требует реализации языка унифицированных выражений ( JSR 341 ) и контекстов и внедрения зависимостей ( CDI / JSR 346 ). Реализации этих спецификаций доступны в современных Java EE-совместимых контейнерах (серверах приложений), но использование Hibernate Validator в средах Java SE требует приобретения и использования отдельных реализаций.

Страница «Начало работы с Hibernate Validator» предоставляет Maven XML, который можно использовать для определения зависимостей от API языка выражений (я использую API языка выражений 3.0 ), Реализацию языка выражений (я использую реализацию языка выражений 2.2.6 ) и Hibernate Validator CDI портативное расширение (я использую Hibernate Validator Portable Extension 5.1.3 Final ). Я также использую Bean Validation API 1.1.0 Final , JBoss Logging 3.3.0 Final и ClassMate 1.2.0 для создания и запуска моих примеров.

Для примеров проверки bean-компонентов, представленных в этом посте, определены три Java-класса. Один класс, Car.java , адаптирован из примера, представленного на странице « Начало работы с Hibernate Validator », и его список кодов показан ниже.

Car.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package dustin.examples;
 
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
 
/**
 * Example adapted from "Getting Started with Hibernate Validator"
 */
public class Car
{
   @NotNull
   private String manufacturer;
 
   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;
 
   @Min(2)
   private int seatCount;
 
   public Car(final String manufacturer, final String licencePlate, final int seatCount)
   {
      this.manufacturer = manufacturer;
      this.licensePlate = licencePlate;
      this.seatCount = seatCount;
   }
 
   public String getManufacturer()
   {
      return manufacturer;
   }
 
   public String getLicensePlate()
   {
      return licensePlate;
   }
 
   public int getSeatCount()
   {
      return seatCount;
   }
 
   @Override
   public String toString()
   {
      return "Car{" +
         "manufacturer='" + manufacturer + '\'' +
         ", licensePlate='" + licensePlate + '\'' +
         ", seatCount=" + seatCount +
         '}';
   }
}

Другой класс, используемый в примерах этого поста, определен в Garage.java и в основном является оболочкой для нескольких экземпляров Car . Его основная цель — помочь проиллюстрировать рекурсивную проверку, поддерживаемую Hibernate Bean Validator.

Garage.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package dustin.examples;
 
import javax.validation.Valid;
import javax.validation.constraints.Size;
 
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
 
/**
 * Holds cars.
 */
public class Garage
{
   @Size(min = 1)
   @Valid
   private final Set<Car> cars = new HashSet<>();
 
   public Garage() {}
 
   public void addCar(final Car newCar)
   {
      cars.add(newCar);
   }
 
   public Set<Car> getCars()
   {
      return Collections.unmodifiableSet(this.cars);
   }
}

Приведенный выше листинг кода Garage использует аннотацию @Valid для указания того, что экземпляры Car содержащиеся в классе, также должны быть проверены («каскадирование проверки»).

Последний класс Java, используемый в примерах этого поста, — это класс, который фактически выполняет проверку двух аннотированных классов проверки компонентов — Car и Garage . Список этого класса показан далее.

HibernateValidatorDemonstration.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package dustin.examples;
 
import static java.lang.System.out;
 
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.Validator;
import java.util.Set;
 
/**
 * Demonstrate use of Hibernate Validator.
 */
public class HibernateValidatorDemonstration
{
   private final Validator validator;
 
   public HibernateValidatorDemonstration()
   {
      final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
      validator = factory.getValidator();
   }
 
   public void demonstrateValidator()
   {
      final Car nullManufacturerCar = new Car(null, "ABC123", 4);
      final Set<ConstraintViolation<Car>> nullMfgViolations = validator.validate(nullManufacturerCar);
      printConstraintViolationsToStandardOutput("Null Manufacturer Example", nullMfgViolations);
 
      final Car nullLicenseCar = new Car("Honda", null, 3);
      final Set<ConstraintViolation<Car>> nullLicenseViolations = validator.validate(nullLicenseCar);
      printConstraintViolationsToStandardOutput("Null License Example", nullLicenseViolations);
 
      final Car oneSeatCar = new Car("Toyota", "123ABC", 1);
      final Set<ConstraintViolation<Car>> tooFewSeatsViolations = validator.validate(oneSeatCar);
      printConstraintViolationsToStandardOutput("Too Few Seats Example", tooFewSeatsViolations);
 
      final Car oneDigitLicenseCar = new Car("General Motors", "I", 2);
      final Set<ConstraintViolation<Car>> tooFewLicenseDigitsViolation = validator.validate(oneDigitLicenseCar);
      printConstraintViolationsToStandardOutput("Too Few License Digits Example", tooFewLicenseDigitsViolation);
 
      final Car nullManufacturerNullLicenseCar = new Car(null, null, 4);
      final Set<ConstraintViolation<Car>> nullMfgLicenseViolation = validator.validate(nullManufacturerNullLicenseCar);
      printConstraintViolationsToStandardOutput("Null Manufacturer and Null License Example", nullMfgLicenseViolation);
 
      final Garage garage = new Garage();
      final Set<ConstraintViolation<Garage>> noCarsInGarage = validator.validate(garage);
      printConstraintViolationsToStandardOutput("No Cars in Garage", noCarsInGarage);
 
      garage.addCar(oneDigitLicenseCar);
      garage.addCar(oneSeatCar);
      garage.addCar(nullManufacturerNullLicenseCar);
      final Set<ConstraintViolation<Garage>> messedUpCarsInGarage = validator.validate(garage);
      printConstraintViolationsToStandardOutput("Messed Up Cars in Garage", messedUpCarsInGarage);
   }
 
   private <T> void printConstraintViolationsToStandardOutput(
      final String title,
      final Set<ConstraintViolation<T>> violations)
   {
      out.println(title);
      for (final ConstraintViolation<T> violation : violations)
      {
         out.println("\t" + violation.getPropertyPath() + " " + violation.getMessage());
      }
   }
 
   public static void main(final String[] arguments)
   {
      final HibernateValidatorDemonstration instance = new HibernateValidatorDemonstration();
      instance.demonstrateValidator();
   }
}

Приведенный выше код имеет несколько вызовов javax.validation.Validator.validate (T, Class <?>) , Которые демонстрируют эффективность аннотаций для классов, экземпляры которых проверяются. Несколько примеров проверяют одно нарушение проверки объекта, пример проверяет множественные нарушения проверки объекта, а последний пример демонстрирует успешное обнаружение каскадного нарушения.

Класс HibernateValidatorDemonstration имеет main(String[]) функцию main(String[]) которая может выполняться в среде Java SE (при условии, что необходимые JAR-файлы находятся в пути к классам времени выполнения). Результат запуска вышеуказанного демонстрационного класса показан ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
Jul 19, 2015 9:30:05 PM org.hibernate.validator.internal.util.Version
INFO: HV000001: Hibernate Validator 5.1.3.Final
Null Manufacturer Example
 manufacturer may not be null
Null License Example
 licensePlate may not be null
Too Few Seats Example
 seatCount must be greater than or equal to 2
Too Few License Digits Example
 licensePlate size must be between 2 and 14
Null Manufacturer and Null License Example
 manufacturer may not be null
 licensePlate may not be null
No Cars in Garage
 cars size must be between 1 and 2147483647
Messed Up Cars in Garage
 cars[].licensePlate size must be between 2 and 14
 cars[].manufacturer may not be null
 cars[].licensePlate may not be null
 cars[].seatCount must be greater than or equal to 2

Вывод

Этот пост продемонстрировал, что Hibernate Bean Validator, эталонная реализация спецификации Bean Validation, может быть выполнена в среде Java SE. В рамках этой демонстрации были также обсуждены и продемонстрированы некоторые базовые концепции, связанные со спецификацией Bean Validation и реализацией Hibernate Bean Validator.

Дополнительные ресурсы

Ссылка: Использование Hibnate Bean Validator в Java SE от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .