Перейти к основному содержимому

Руководство по ParameterMessageInterpolator

· 4 мин. чтения

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 .