1. Обзор
Одной из особенностей Java JSR 380 является разрешение выражений при интерполяции сообщений проверки с параметрами.
Когда мы используем Hibernate Validator, нам необходимо добавить одну из унифицированных реализаций Java JSR 341 в качестве зависимости к нашему проекту. JSR 341 также называется API языка выражений.
Однако добавление дополнительной библиотеки может быть обременительным, если нам не нужно поддерживать выражения синтаксического анализа в соответствии с нашим вариантом использования.
В этом кратком руководстве мы рассмотрим, как настроить ParameterMessageInterpolator
в Hibernate Validator.
2. Интерполяторы сообщений
Помимо основ проверки Java -бина, Bean Validation API MessageInterpolator
представляет собой абстракцию, которая дает нам способ выполнять простые интерполяции без хлопот синтаксического анализа выражений.
Кроме того, Hibernate Validator предлагает ParameterMessageInterpolator,
не основанный на выражениях, и поэтому нам не нужны дополнительные библиотеки для его настройки.
3. Настройка пользовательских интерполяторов сообщений
Чтобы удалить зависимость от языка выражений, мы можем использовать пользовательские интерполяторы сообщений и настроить Hibernate Validator без поддержки выражений.
Давайте покажем несколько удобных способов настройки пользовательских интерполяторов сообщений. В нашем случае мы будем использовать встроенный ParameterMessageInterpolator .
3.1. Настройка ValidatorFactory
Один из способов настроить собственный интерполятор сообщений — настроить ValidatorFactory
при начальной загрузке.
Таким образом, мы можем создать экземпляр ValidatorFactory с помощью
ParameterMessageInterpolator
:
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
.configure()
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory();
3.2. Настройка валидатора
Точно так же мы можем установить ParameterMessageInterpolator
при инициализации экземпляра Validator :
Validator validator = validatorFactory.usingContext()
.messageInterpolator(new ParameterMessageInterpolator())
.getValidator();
4. Выполнение проверок
Чтобы увидеть, как работает ParameterMessageInterpolator
, нам нужен образец Java-бина с некоторыми аннотациями JSR 380.
4.1. Пример Java-бина
Давайте определим наш образец Java-бина Person
:
public class Person {
@Size(min = 10, max = 100, message = "Name should be between {min} and {max} characters")
private String name;
@Min(value = 18, message = "Age should not be less than {value}")
private int age;
@Email(message = "Email address should be in a correct format: ${validatedValue}")
private String email;
// standard getters and setters
}
4.2. Проверка параметров сообщения
Конечно, для выполнения наших проверок мы должны использовать экземпляр Validator, доступ к которому осуществляется из ValidatorFactory
,
который мы уже настроили ранее .
Итак, нам нужно получить доступ к нашему валидатору
:
Validator validator = validatorFactory.getValidator();
После этого мы можем написать наш тестовый метод для поля имени :
@Test
public void givenNameLengthLessThanMin_whenValidate_thenValidationFails() {
Person person = new Person();
person.setName("John Doe");
person.setAge(18);
Set<ConstraintViolation<Person>> violations = validator.validate(person);
assertEquals(1, violations.size());
ConstraintViolation<Person> violation = violations.iterator().next();
assertEquals("Name should be between 10 and 100 characters", violation.getMessage());
}
Сообщение проверки корректно интерполируется с переменными {min}
и {max}
:
Name should be between 10 and 100 characters
Далее напишем аналогичный тест для поля age :
@Test
public void givenAgeIsLessThanMin_whenValidate_thenValidationFails() {
Person person = new Person();
person.setName("John Stephaner Doe");
person.setAge(16);
Set<ConstraintViolation<Person>> violations = validator.validate(person);
assertEquals(1, violations.size());
ConstraintViolation<Person> violation = violations.iterator().next();
assertEquals("Age should not be less than 18", violation.getMessage());
}
Точно так же сообщение проверки правильно интерполируется с переменной {value}
, как мы и ожидали:
Age should not be less than 18
4.3. Тестирование выражений
Чтобы увидеть, как ParameterMessageInterpolator
ведет себя с выражениями, давайте напишем еще один тест для поля электронной почты
, который включает простое выражение ${validatedValue}
:
@Test
public void givenEmailIsMalformed_whenValidate_thenValidationFails() {
Person person = new Person();
person.setName("John Stephaner Doe");
person.setAge(18);
person.setEmail("johndoe.dev");
Set<ConstraintViolation<Person>> violations = validator.validate(person);
assertEquals(1, violations.size());
ConstraintViolation<Person> violation = violations.iterator().next();
assertEquals("Email address should be in a correct format: ${validatedValue}", violation.getMessage());
}
На этот раз выражение ${validatedValue}
не интерполируется.
ParameterMessageInterpolator
поддерживает только интерполяцию параметров, а не синтаксический анализ выражений, использующих нотацию $ .
Вместо этого он просто возвращает их без интерполяции.
5. Вывод
В этой статье мы узнали, для чего нужен ParameterMessageInterpolator
и как его настроить в Hibernate Validator.
Как всегда, все примеры, используемые в этом руководстве, доступны на GitHub .