В приложении CD-Book Store клиент покупает товары, заказанные онлайн, и эти товары доставляются на его почтовый адрес. Для обеспечения такой доставки приложению нужна верная информация об имени клиента, адрес электронной почты и адрес доставки. Поскольку у нас есть дата рождения клиента, программа может ежегодно присылать ему соответствующее поздравление. В листинге 3.22 показан компонент Customer, включающий в себя несколько встроенных ограничений, налагаемых на атрибуты (firstname не может быть нулевым, а дата dateOfBirth должна относиться к прошлому). Здесь также есть ограничение @Email, которое мы разработаем. Код проверяет, является ли строка String валидным адресом электронной почты.
public class Customer {
··@NotNull @Size(min = 2)
··private String firstName;
··private String lastName;
··@Email
··private String email;
··private String phoneNumber;
··@Past
··private Date dateOfBirth;
··private Address deliveryAddress;
··// Конструкторы, геттеры, сеттеры
}
У Customer может быть ноль или один адрес доставки. Address — это компонент, включающий всю информацию, необходимую для доставки товара по указанному адресу: улица, город, штат, ZIP-код и страна. В листинге 3.23 показан компонент Address с ограничением @NotNull, налагаемым на важнейшие атрибуты (street1, city и zipcode), а также с ограничением @ZipCode, проверяющим валидность ZIP-кода (это ограничение будет разработано позже).
public class Address {
··@NotNull
··private String street1;
··private String street2;
··@NotNull
··private String city;
··private String state;
··@NotNull @ZipCode
··private String zipcode;
··private String country;
··// Конструкторы, геттеры, сеттеры
}
Ограничение @Email не встроено в систему валидации компонентов, поэтому нам самим придется его разработать. Нам не понадобится класс реализации (@Constraint(validatedBy = {})), так как вполне работоспособным будет обычная ограничивающая аннотация с регулярным выражением (@Pattern) и заданным размером. В листинге 3.24 показана ограничивающая аннотация @Email.
@Size(min = 7)
@Pattern(regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
····+ "[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
····+ "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
@ReportAsSingleViolation
@Constraint(validatedBy = {})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
public @interface Email {
··String message() default " {org.agoncal.book.javaee7.chapter03.Email.message}";
··Class[] groups() default {};
··Class[] payload() default {};
··@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
··@Retention(RUNTIME)
··@interface List {
····Email[] value();
··}
}
Обратите внимание: в листинге 3.24 сообщение об ошибке представляет собой ключ пакета, определяемый в файле META-INF/ValidationMessages.properties.
org.agoncal.book.javaee7.chapter03.Email.message=invalid email address