Не так давно в Яве не существовало стандарта, описывающего способ валидации данных. Каждый выкручивался как мог, писались (и пишутся) свои поделки а так же используются некоторые возможности широко распространенных сервисов как Spring или Hibernate. Наибольшей проблемой было то, что валидация могла быть реализована отдельно от предметной модели и быть редунданто расбросанной по фронт- и бэкэнду. Теперь, при помощи стандарта JSR 303: Bean Validation (практически это явлается стандартизированным валидатором Hibernate) становится возможным следовать принципу «Don't Repeat Yourself»: объявлять ограничения для данных прямо в предметной модели и валидировать данные где угодно, хоть на сервере, хоть в десктопном приложении.
Таким образом валидация данных проводится в три базовых шага:
На данный момент существует лишь малое количество аннотаций в еще пока не выпущенном стандарте. Но есть не малая вероятность что такие аннотации как Email, @CreditCard, Password итд. будут доступны хотя бы через провайдеров имплементации стандарта.
На этом закончим знакомство с JSR 303. А с такими подробностями как расширение/написание собственных ограничений, интернализации сообщений, конфигурации фэктори и прочим можно ознакомится и в самом стандарте
P.S. Для запуска кода в примере использовалась имплементация Hibernate 4.0.0 Beta2, приятных экспериментов!
Пример использования
package test.validator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
public class User {
@NotNull(message="Имя должно быть задано")
String firstname;
@NotNull(message="Фамилия должна быть задана")
@Size(min = 3, message="Длина фамилии должна быть больше трех")
String lastname;
@NotNull(message="Имэйл должен быть задан")
@Pattern(regexp = "^(?:[a-zA-Z0-9_'^&/+-])+(?:\\.(?:[a-zA-Z0-9_'^&/+-])+)" +
"*@(?:(?:\\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\\.)" +
"{3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\]?)|(?:[a-zA-Z0-9-]+\\.)" +
"+(?:[a-zA-Z]){2,}\\.?)$",
message = "заданный имэйл не может существовать")
String email;
@Override
public String toString() {
return String.format("firstname: [%s], lastname: [%s], email: [%s]",
firstname, lastname, email);
}
public static void validate(Object object, Validator validator) {
Set<ConstraintViolation<Object>> constraintViolations = validator
.validate(object);
System.out.println(object);
System.out.println(String.format("Кол-во ошибок: %d",
constraintViolations.size()));
for (ConstraintViolation<Object> cv : constraintViolations)
System.out.println(String.format(
"Внимание, ошибка! property: [%s], value: [%s], message: [%s]",
cv.getPropertyPath(), cv.getInvalidValue(), cv.getMessage()));
}
public static void main(String[] args) {
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
User user = new User();
validate(user, validator);
user.firstname = "Вася";
validate(user, validator);
user.lastname = "Пу";
validate(user, validator);
user.lastname = "Пупкин";
validate(user, validator);
user.email = "вася пупкин@example.com";
validate(user, validator);
user.email = "vasya.poupkine@example.com";
validate(user, validator);
}
}
* This source code was highlighted with Source Code Highlighter.
Таким образом валидация данных проводится в три базовых шага:
- Объявление «ограничений» (constraints) на данные в модели при помощи аннотаций
- Получение валидатора через фэктори
- валидация объектов и обработка сообщений о нарушениях объявленных рамок (ConstraintViolations)
На данный момент существует лишь малое количество аннотаций в еще пока не выпущенном стандарте. Но есть не малая вероятность что такие аннотации как Email, @CreditCard, Password итд. будут доступны хотя бы через провайдеров имплементации стандарта.
На этом закончим знакомство с JSR 303. А с такими подробностями как расширение/написание собственных ограничений, интернализации сообщений, конфигурации фэктори и прочим можно ознакомится и в самом стандарте
P.S. Для запуска кода в примере использовалась имплементация Hibernate 4.0.0 Beta2, приятных экспериментов!