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

Обработчик аннотаций Hibernate Validator в деталях

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

1. Обзор

Легко неправильно использовать ограничения проверки bean -компонентов. Например, мы можем случайно украсить атрибут String ограничением @Future . Такие ошибки могут привести к непредсказуемым ошибкам во время выполнения.

К счастью, обработчик аннотаций Hibernate Validator помогает обнаруживать эти проблемы во время компиляции. Благодаря ошибкам, которые он выдает, мы можем отловить эти ошибки раньше.

В этом руководстве мы рассмотрим, как настроить процессор, и рассмотрим некоторые распространенные проблемы, которые он может нам найти.

2. Конфигурация

2.1. Монтаж

Давайте начнем с добавления зависимости обработчика аннотаций в наш pom.xml:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-Averbose=true</arg>
<arg>-AmethodConstraintsSupported=true</arg>
<arg>-AdiagnosticKind=ERROR</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.2.0.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>

Следует отметить, что версия 7 этого инструмента совместима только с ограничениями jakarta.validation :

<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.1</version>
</dependency>

Процессор также предоставляет руководство по его настройке для основных IDE Java.

2.2. Параметры компилятора

Настроим параметры компилятора нашего процессора:

<compilerArgs>
<arg>-Averbose=true</arg>
<arg>-AmethodConstraintsSupported=true</arg>
<arg>-AdiagnosticKind=ERROR</arg>
</compilerArgs>

Во-первых, параметр DiagnosticKind нацелен на уровень ведения журнала. Предпочтительно оставить значение ERROR по умолчанию , чтобы выявить проблемы во время компиляции. Все допустимые значения указаны в перечислении Diagnostic.Kind . ``

Затем, если мы хотим ограничить проверку аннотаций только геттерами, мы должны установить для параметра methodConstraintsSupported значение false .

Здесь мы установили для verbose значение true , чтобы получить больше вывода, но мы можем установить для него значение false , если нам не нужно много вывода журнала.

3. Общие проблемы с ограничениями

Процессор аннотаций поставляется с набором предопределенных ошибок для проверки . Рассмотрим подробнее три из них на примере простого класса Message :

public class Message {
// constructor omitted
}

3.1. Только геттеры могут быть аннотированы

Во-первых, этой проблемы не должно быть с параметрами процессора по умолчанию. Как следует из названия, он появляется, когда мы аннотируем не-геттер-метод. Нам нужно установить для параметра methodConstraintsSupported значение true , чтобы разрешить это.

Давайте добавим в наш класс Message три аннотированных метода:

@Min(3)
public boolean broadcast() {
return true;
}

@NotNull
public void archive() {
}

@AssertTrue
public boolean delete() {
return false;
}

Затем мы устанавливаем для параметра methodConstraintsSupported значение false в нашей конфигурации:

<compilerArgs>
<arg>AmethodConstraintsSupported=false</arg>
</compilerArgs>

Наконец, три метода заставят процессор обнаружить нашу проблему:

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\methodvalidation\model\ReservationManagement.java:[25,4] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[55,4] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[38,5] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[47,4] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[INFO] 4 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.457 s
[INFO] Finished at: 2022-01-20T21:42:47Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project javaxval: Compilation failure: Compilation failure:
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\methodvalidation\model\ReservationManagement.java:[25,4] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[55,4] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[38,5] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[47,4] error: Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.

Интересно отметить, что проблема затрагивает метод удаления , хотя технически он правильно аннотирован.

В следующих разделах мы установим для параметра methodConstraintsSupported значение true .

3.2. Только непустые методы могут быть аннотированы

Эта проблема гласит, что мы не должны украшать методы void проверками ограничений. Мы можем увидеть это в действии, аннотировав метод архивации в нашем классе Message :

@NotNull
public void archive() {
}

Это заставляет процессор вызывать ошибку:

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[45,4] error: Void methods may not be annotated with constraint annotations.
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.078 s
[INFO] Finished at: 2022-01-20T21:35:08Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project javaxval: Compilation failure
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[45,4] error: Void methods may not be annotated with constraint annotations.

3.3. Неподдерживаемый тип для аннотации

Эта последняя проблема является наиболее распространенной. Это происходит, когда целевой тип данных аннотации не соответствует целевому свойству. Чтобы увидеть его в действии в нашем классе Message , давайте добавим неправильно аннотированный атрибут String в наш класс Message :

@Past 
private String createdAt;

Произойдет ошибка из-за аннотации @Past . На самом деле, только типы даты могут использовать это ограничение:

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] ${home}\foreach\tutorials\javaxval\hibernate\validator\ap\Message.java:[20,5] error: The annotation @Past is disallowed for this data type.
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.892 s
[INFO] Finished at: 2022-01-20T21:29:15Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project javaxval: Compilation failure
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[20,5] error: The annotation @Past is disallowed for this data type.

Мы получим аналогичную ошибку, если применим неправильную аннотацию к методу с неподдерживаемым типом возвращаемого значения:

@Min(3)
public boolean broadcast() {
return true;
}

Сообщение об ошибке процессора такое же, как и предыдущее:

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[37,5] error: The annotation @Min is disallowed for the return type of this method.
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.761 s
[INFO] Finished at: 2022-01-20T21:38:28Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project javaxval: Compilation failure
[ERROR] ${home}\foreach\tutorials\javaxval\src\main\java\com\foreach\javaxval\hibernate\validator\ap\Message.java:[37,5] error: The annotation @Min is disallowed for the return type of this method.

4. Вывод

В этой статье мы попробовали обработчик аннотаций Hibernate Validator.

Сначала мы установили его и настроили его параметры. Затем мы исследовали его поведение с помощью трех общих проблем с ограничениями.

Как всегда, пример кода можно найти на GitHub .