Статьи

Проверка бобов стала проще с помощью JSR 303

JSR 303 (Bean Validation) — это спецификация Java API для проверки JavaBean в Java EE и Java SE. Проще говоря, это обеспечивает простой способ гарантировать, что свойства ваших JavaBean (ов) имеют правильные значения в них. Цель этого поста — показать, как использовать API Bean Validation в вашем проекте.

    Для начала представьте, что вы создаете следующий Facebook, и вам нужно будет зарегистрироваться, чтобы использовать ваше приложение.
Для успешной регистрации потенциальные участники должны предоставить следующие данные: фамилия, имя, пол, адрес электронной почты и дата рождения. Кроме того, лицо, которое регистрируется, должно быть от 18 до 150 лет включительно.

    До JSR 303 вам, вероятно, потребовалась бы куча операторов if-else для выполнения вышеуказанных требований.
К счастью, больше нет.

    Мы начнем с создания JavaBean с именем ‘Member’, который будет содержать все интересующие нас свойства.
package validationapiblog.model;

import java.util.Date;
import validationapiblog.enums.Gender;

/**
 *
 * @author Adedayo Ominiyi
 */
public class Member {

    private String lastName = null;
    private String firstName = null;
    private Gender gender = null;
    private String emailAddress = null;
    private Date dateOfBirth = null;

    public Member() {
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public Integer getAge() {
        if (this.dateOfBirth != null) {
            // calculate age of member here
        }
        return null;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
}

Гендерное свойство является простым перечислением и показано ниже

package validationapiblog.enums;

/**
 *
 * @author Adedayo Ominiyi
 */
public enum Gender {
    MALE, FEMALE;
}


Теперь у нас есть кусочки головоломки.
Следующим шагом является загрузка реализации JSR 303. Для этого поста мы будем использовать эталонную реализацию, а именно
Hibernate Validator . Версия на момент написания этого поста — 4.2.0 Final. После загрузки вы должны добавить следующие 4 фляги в classpath вашего проекта:
  • Hibernate-валидатор-4.2.0.Final.jar
  • спящий режим-валидатор-аннотаций-процессор 4.2.0.Final.jar
  • SLF4J-апи-1.6.1.jar
  • валидация-апи-1.0.0.GA.jar

Как только это будет сделано, вы просто аннотируете JavaBean ‘Member’, который мы создали ранее, чтобы указать, какие свойства необходимо проверить.
Вы можете аннотировать либо поля, либо методы доступа (или метода получения) JavaBean. В этом посте я буду комментировать методы доступа.
package validationapiblog.model;

import java.util.Date;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
import validationapiblog.enums.Gender;

/**
 *
 * @author Adedayo Ominiyi
 */
public class Member {

    private String lastName = null;
    private String firstName = null;
    private Gender gender = null;
    private String emailAddress = null;
    private Date dateOfBirth = null;

    public Member() {
    }

    @NotNull(message = "First name is compulsory")
    @NotBlank(message = "First name is compulsory")
    @Pattern(regexp = "[a-z-A-Z]*", message = "First name has invalid characters")
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @NotNull(message = "Gender is compulsory")
    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    @NotNull(message = "Last name is compulsory")
    @NotBlank(message = "Last name is compulsory")
    @Pattern(regexp = "[a-z-A-Z]*", message = "Last name has invalid characters")
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Past(message = "Date of Birth must be the past")
    @NotNull
    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    @Min(value = 18, message = "Age must be greater than or equal to 18")
    @Max(value = 150, message = "Age must be less than or equal to 150")
    public Integer getAge() {
        if (this.dateOfBirth != null) {
            // calculate age of member here
        }
        return null;
    }

    @NotNull(message="Email Address is compulsory")
    @NotBlank(message="Email Address is compulsory")
    @Email(message = "Email Address is not a valid format")
    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
}

Обратите внимание, что это только некоторые из аннотаций, доступных в JSR 303. Кроме того, Hibernate Validator представляет несколько своих собственных, которых нет в спецификации.
Не стесняйтесь изучать аннотации не в этом посте, в свободное время вы можете найти что-то интересное Существует также возможность создать свой собственный валидатор, если возникнет такая необходимость. Теперь давайте рассмотрим используемые аннотации:
  • @NotNull — проверяет, что аннотированное значение не является нулевым. К сожалению, он не проверяет пустые строковые значения
  • @Pattern — Проверяет, соответствует ли аннотированная строка заданному регулярному выражению. Мы использовали его, чтобы гарантировать, что свойства фамилии и имени имеют допустимые строковые значения
  • @Past — аннотированный элемент должен быть датой в прошлом.
  • @Min — аннотированный элемент должен быть числом, значение которого должно быть больше или равно указанному минимуму
  • @Max — аннотированный элемент должен быть числом, значение которого должно быть меньше или равно указанному максимуму
  • @NotBlank — проверяет, что аннотированная строка не равна нулю, а усеченная длина больше 0. Эта аннотация отсутствует в JSR 303
  • @Email — проверяет, является ли указанная строка действительным адресом электронной почты. Этой аннотации тоже нет в JSR 303

Для проверки правильности мы могли бы использовать модульный тест, как показано ниже. 
package validationapiblog.test;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import validationapiblog.model.Member;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Adedayo Ominiyi
 */
public class ValidationAPIUnitTest {

    public ValidationAPIUnitTest() {
    }

    @Test
    public void testMemberWithNoValues() {
        Member member = new Member();

        // validate the input
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<constraintviolation<member>> violations = validator.validate(member);
        assertEquals(violations.size(), 5);
    }
}
</constraintviolation<member>

В заключение вам следует поэкспериментировать с JSR 303 и посмотреть, какие аннотации вам нравятся.
Спасибо и веселитесь.

Первоначальный URL:
проверка бинов стала проще с JSR 303