Baza Wiedzy

Bean Validation

    Czym jest Bean Validation🔗

    Bean Validation jest specyfikacją wchodzącą w skład platformy Java EE i jest oznaczona kodami JSR-303 (wersja 1.0) oraz JSR-349 (wersja 1.1). Aktualnie trwają prace nad wersją 2.0. Najpopularniejszą i jednocześnie referencyjną implementacją jest Hibernate Validator. Alternatywą jest projekt Apache BVal.

    bean validation diagram

    Bean Validation daje możliwość prostego weryfikowania poprawności pól obiektów w oparciu o zdefiniowane ograniczenia, które stosujemy w postaci adnotacji dodanych nad polami klasami lub metodami dostępowymi (getterami).

    public class Person {
        @NotNull
        private String firstName;
        @NotNull
        private String lastName;
        @Email
        private String email;
        @Min(1)
        private int age;
    }

    Ważną cechą Bean Validation jest integracja z pozostałymi specyfikacjami platformy Java EE takimi jak JPA, czy JAX-RS. BV została również zaadoptowana w Springu, gdzie integruje się także z JPA, Spring Data, czy Spring MVC.

    Ograniczenia🔗

    Bean Validation definiuje podstawowy zestaw ograniczeń, które powinny nas zadowolić w większości typowych zastosowań:

      • @AssertFalse - musi mieć wartość false

      • @AssertTrue - musi mieć wartość true

      • @Min - określa wartość minimalną

      • @Max - określa wartość maksymalną

      • @DecimalMin - podobnie jak @Min, ale pozwala także na weryfikację liczby w postaci Stringa

      • @DecimalMax -podobnie jak @Max, ale pozwala także na weryfikację liczby w postaci Stringa

      • @Null - musi być null

      • @NotNull - nie może być null

      • @Digits - określa ilość cyfr przed i po przecinku, z ilu może składać się liczba. Wspiera typy całkowitoliczbowe, ich wrappery oraz typy BigInteger i BigDecimal

      • @Future - data musi być z przyszłości

      • @Past - data musi być z przeszłości

      • @Pattern - wartość musi być zgodna z podanym wyrażeniem regularnym

      • @Size - określa minimalną i maksymalną ilość znaków w Stringu lub minimalną i maksymalną ilość elementów w kolekcjach i tablicach

      Oprócz wyżej wymienionych istnieje zestaw ograniczeń pochodzących z biblioteki Hibernate Validator:

        • @CreditCardNumber

        • @EAN

        • @Email

        • @Length

        • @LuhnCheck

        • @Mod10Check

        • @Mod11Check

        • @NotBlank

        • @NotEmpty

        • @Range

        • @SafeHtml

        • @ScriptAssert

        • @URL

        Przykład🔗

        Jeżeli chcesz skorzystać z walidacji w swoim projekcie musisz dodać bibliotekę Hibernate Validator. Najłatwiej jest stworzyć projekt w oparciu o Mavena lub Gradle dodając odpowiednią zależność:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.3.3.Final</version>
        </dependency>

        W przypadku projektu, gdzie wolimy wszystko robić ręcznie możemy pobrać Hibernate Validatora z oficjalnej strony i wybrać w projekcie opcję Add to Build Path.

        build path validation

        W projekcie definiujemy klasę reprezentującą osobę, dodając do niej ograniczenia:

          • imię ani nazwisko nie może być wartością null

          • email musi być poprawnym adresem email

          • wiek musi wynosić minimum 1

          Person.java

          package pl.javastart.model;
          
          import javax.validation.constraints.Min;
          import javax.validation.constraints.NotNull;
          
          import org.hibernate.validator.constraints.Email;
          
          public class Person {
              @NotNull
              private String firstName;
              @NotNull
              private String lastName;
              @Email
              private String email;
              @Min(1)
              private int age;
              
              public Person(String firstName, String lastName, String email, int age) {
                  this.firstName = firstName;
                  this.lastName = lastName;
                  this.email = email;
                  this.age = age;
              }
              public String getFirstName() {
                  return firstName;
              }
              public void setFirstName(String firstName) {
                  this.firstName = firstName;
              }
              public String getLastName() {
                  return lastName;
              }
              public void setLastName(String lastName) {
                  this.lastName = lastName;
              }
              public String getEmail() {
                  return email;
              }
              public void setEmail(String email) {
                  this.email = email;
              }
              public int getAge() {
                  return age;
              }
              public void setAge(int age) {
                  this.age = age;
              }
          }

          A w klasie testowej przeprowadzamy walidację przykładowego obiektu z błędnie ustawionymi wartościami.

          ValidationExample.java

          package pl.javastart;
          
          import java.util.Set;
          
          import javax.validation.ConstraintViolation;
          import javax.validation.Validation;
          import javax.validation.Validator;
          import javax.validation.ValidatorFactory;
          
          import pl.javastart.model.Person;
          
          public class ValidationExample {
          
              public static void main(String[] args) {
                  ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
                  Validator validator = factory.getValidator();
                  
                  //brak nazwiska, błędny email i błędny wiek
                  Person person = new Person("Jan", null, "zlyEmail", 0);
                  Set<ConstraintViolation<Person>> errors = validator.validate(person);
                  errors.forEach(error -> System.err.println(error.getPropertyPath() + " " + error.getMessage()));
              }
          }

          W konsoli zobaczymy wydruk ze złamanymi ograniczeniami, które są reprezentowane przez obiekty typu ConstraintViolation.

          constraint violations

          Przykład na Github

          Najlepszy newsletter o Javie w Polsce

          Czy chcesz otrzymywać nowości ze świata Javy oraz przykładowe pytania rekrutacyjne? Zapisz się na newsletter i bądź na bieżąco! Otrzymasz także ekskluzywne materiały oraz informacje o nowych kursach i promocjach.

          Nikomu nie udostępniamy Twojego maila, a jeśli zechcesz to w każdej chwili możesz się wypisać.

          Komentarze do artykułu

          Wyłączyliśmy możliwość dodawania komentarzy. Poniżej znajdziesz archiwalne wpisy z czasów gdy strona była jeszcze hobbystycznym blogiem. Zapraszamy natomiast do zadawnia pytań i dyskusji na naszej grupe na facebooku.