Рубрики
Без рубрики

Интерполяция сообщений весенней проверки

Узнайте, как работает интерполяция сообщений Spring по умолчанию и как создать пользовательский механизм интерполяции сообщений

Автор оригинала: baeldung.

1. введение

Интерполяция сообщений-это процесс, используемый для создания сообщений об ошибках для проверки Java bean ограничений. Например, мы можем просмотреть сообщения, указав значение null для поля, аннотированного ограничениями javax.validation..NotNull аннотация.

В этом уроке мы узнаем, как использовать интерполяцию сообщений Spring по умолчанию и как создать собственный механизм интерполяции.

Чтобы увидеть примеры других библиотек , предоставляющих ограничения, помимо javax.validation , взгляните на Конкретные ограничения Hibernate Validator . Мы также можем создать пользовательскую аннотацию проверки весны .

2. Интерполяция Сообщений По Умолчанию

Прежде чем перейти к фрагментам кода, давайте рассмотрим пример ответа HTTP 400 с сообщением о нарушении ограничений по умолчанию @NotNull :

{
    ....
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            ....
            "defaultMessage": "must not be null",
            ....
        }
    ],
    "message": "Validation failed for object='notNullRequest'. Error count: 1",
    ....
}

Spring извлекает сведения о сообщении о нарушении ограничений из дескрипторов сообщений. Каждое ограничение определяет свой дескриптор сообщения по умолчанию с помощью атрибута message . Но, конечно, мы можем перезаписать его пользовательским значением.

В качестве примера мы создадим простой контроллер REST с методом POST:

@RestController
public class RestExample {

    @PostMapping("/test-not-null")
    public void testNotNull(@Valid @RequestBody NotNullRequest request) {
        // ...
    }
}

Тело запроса будет сопоставлено объекту NotNull Request , который имеет только одно поле String с аннотацией @NotNull :

public class NotNullRequest {

    @NotNull(message = "stringValue has to be present")
    private String stringValue;

    // getters, setters
}

Теперь, когда мы отправим запрос POST, который не прошел эту проверку, мы увидим наше пользовательское сообщение об ошибке:

{
    ...
    "errors": [
        {
            ...
            "defaultMessage": "stringValue has to be present",
            ...
        }
    ],
    ...
}

Единственное значение, которое изменяется, – это Сообщение по умолчанию . Но мы все равно получаем много информации о кодах ошибок, имени объекта, имени поля и т. Д. Чтобы ограничить количество отображаемых значений, мы можем реализовать Пользовательскую обработку сообщений об ошибках для REST API .

3. Интерполяция с выражениями сообщений

Весной мы можем использовать Унифицированный язык выражений для определения наших дескрипторов сообщений . Это позволяет определять сообщения об ошибках на основе условной логики, а также включает расширенные параметры форматирования .

Чтобы понять это более ясно, давайте рассмотрим несколько примеров.

В каждой аннотации ограничения мы можем получить доступ к фактическому значению поля, которое проверяется:

@Size(
  min = 5,
  max = 14,
  message = "The author email '${validatedValue}' must be between {min} and {max} characters long"
)
private String authorEmail;

Наше сообщение об ошибке будет содержать как фактическое значение свойства, так и min и max параметры аннотации @Size :

"defaultMessage": "The author email '[email protected]' must be between 5 and 14 characters long"

Обратите внимание, что для доступа к внешним переменным мы используем синтаксис $ {} , но для доступа к другим свойствам из аннотации проверки мы используем {} .

Также возможно использование тернарного оператора:

@Min(
  value = 1,
  message = "There must be at least {value} test{value > 1 ? 's' : ''} in the test case"
)
private int testCount;

Spring преобразует тернарный оператор в одно значение в сообщении об ошибке:

"defaultMessage": "There must be at least 2 tests in the test case"

Мы также можем вызывать методы для внешних переменных:

@DecimalMin(
  value = "50",
  message = "The code coverage ${formatter.format('%1$.2f', validatedValue)} must be higher than {value}%"
)
private double codeCoverage;

Неверный ввод приведет к появлению сообщения об ошибке с отформатированным значением:

"defaultMessage": "The code coverage 44.44 must be higher than 50%"

Как мы можем видеть из этих примеров, некоторые символы, такие как {, }, $, и / используются в выражениях сообщений, поэтому нам нужно экранировать их символом обратной косой черты, прежде чем использовать их буквально: \{, \}, \$, и \\ .

4. Интерполяция Пользовательских Сообщений

В некоторых случаях мы хотим реализовать пользовательский механизм интерполяции сообщений . Для этого мы должны сначала реализовать javax.validation.Messageinterpolator Интерфейс:

public class MyMessageInterpolator implements MessageInterpolator {
    private final MessageInterpolator defaultInterpolator;

    public MyMessageInterpolator(MessageInterpolator interpolator) {
        this.defaultInterpolator = interpolator;
    }

    @Override
    public String interpolate(String messageTemplate, Context context) {
        messageTemplate = messageTemplate.toUpperCase();
        return defaultInterpolator.interpolate(messageTemplate, context);
    }

    @Override
    public String interpolate(String messageTemplate, Context context, Locale locale) {
        messageTemplate = messageTemplate.toUpperCase();
        return defaultInterpolator.interpolate(messageTemplate, context, locale);
    }
}

В этой простой реализации мы просто меняем сообщение об ошибке на верхний регистр. Таким образом, наше сообщение об ошибке будет выглядеть следующим образом:

"defaultMessage": "THE CODE COVERAGE 44.44 MUST BE HIGHER THAN 50%"

Нам также нужно зарегистрировать наш интерполятор в javax.validation.Валидация завод:

Validation.byDefaultProvider().configure().messageInterpolator(
  new MyMessageInterpolator(
    Validation.byDefaultProvider().configure().getDefaultMessageInterpolator())
);

5. Заключение

В этой статье мы узнали, как работает интерполяция сообщений Spring по умолчанию и как создать пользовательский механизм интерполяции сообщений.

И, как всегда, весь исходный код доступен на GitHub .