3.5.2.4.4. Validator

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

Следует отличать валидацию от проверки типа данных. Если для некоторого компонента, например TextField, задан тип, отличный от строкового (это происходит при связывании с атрибутом сущности или назначении datatype), то компонент не позволяет ввести значение, не удовлетворяющее этому типу - при потере фокуса или нажатии Enter пользователю будет показано сообщение об ошибке.

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

Фреймворк уже содержит несколько реализаций наиболее часто используемых валидаторов, которые можно применять в проектах:

В XML-дескрипторе экрана такие валидаторы для компонента задаются во вложенном элементе validators.

Валидатор можно установить с помощью интерфейса CUBA Studio. Пример добавления валидатора к компоненту TextField:

gui validator

Каждый валидатор является Prototype бином, и если вы хотите использовать валидаторы из Java-кода, вы можете загрузить их с помощью BeanLocator.

Некоторые валидаторы используют Groovy в сообщении об ошибке. Это означает, что в сообщение об ошибке можно передать параметры (например, $value). Эти параметры учитывают языковую локаль пользователя.

В качестве валидатора можно использовать кастомный Java-класс, реализующий интерфейс Consumer.

В XML-дескрипторе экрана кастомный валидатор для компонента задается во вложенном элементе validator.

Если валидатор реализован внутренним классом, то он должен быть объявлен с модификатором static, а его имя для загрузки отделяется символом "$", например:

<validator class="com.sample.sales.gui.AddressEdit$ZipValidator"/>

Валидатор-класс можно назначить компоненту не только в XML-дескрипторе экрана, но и программно, передавая экземпляр валидатора в метод addValidator() компонента.

Пример создания класса валидатора почтового индекса:

public class ZipValidator implements Consumer<String> {
    @Override
    public void accept(String s) throws ValidationException {
        if (s != null && s.length() != 6)
            throw new ValidationException("Zip must be of 6 characters length");
    }
}

Использование валидатора почтового индекса для текстового поля TextField:

<textField id="zipField" property="zip">
    <validator class="com.company.sample.web.ZipValidator"/>
</textField>

Пример программного задания валидатора:

zipField.addValidator(value -> {
    if (value != null && value.length() != 6)
        throw new ValidationException("Zip must be of 6 characters length");
});

Ниже мы рассмотрим предопределенные валидаторы.

DecimalMaxValidator

Проверяет, что значение меньше или равно указанному максимальному значению. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer и String, представляющий значение BigDecimal с текущей локалью.

Валидатор имеет следующие атрибуты:

  • value − максимальное значение (обязательный атрибут);

  • inclusive − если атрибут установлен в true, вводимое значение должно быть меньше или равно указанному максимальному значению. Значение по умолчанию − true;

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменные $value и $max для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.decimalMaxInclusive

  • validation.constraints.decimalMax

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <decimalMax value="10000" inclusive="false" message="Value '$value' cannot be greater than `$max`"/>
    </validators>
</textField>

Использование в Java коде:

DecimalMaxValidator maxValidator = beanLocator.getPrototype(DecimalMaxValidator.NAME, new BigDecimal(100));
numberField.addValidator(maxValidator);
DecimalMinValidator

Проверяет, что значение больше или равно указанному минимальному значению. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer и String, представляющий значение BigDecimal с текущей локалью.

Валидатор имеет следующие атрибуты:

  • value − минимальное значение (обязательный атрибут);

  • inclusive − если атрибут установлен в true, вводимое значение должно быть больше или равно указанному минимальному значению. Значение по умолчанию − true;

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменные $value и $min для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.decimalMinInclusive

  • validation.constraints.decimalMin

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <decimalMin value="100" inclusive="false" message="Value '$value' cannot be less than `$min`"/>
    </validators>
</textField>

Использование в Java коде:

DecimalMinValidator minValidator = beanLocator.getPrototype(DecimalMinValidator.NAME, new BigDecimal(100));
numberField.addValidator(minValidator);
DigitsValidator

Проверяет, что значение − это число в пределах обозначенного диапазона. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer и String, представляющий значение BigDecimal с текущей локалью.

Валидатор имеет следующие атрибуты:

  • integer − количество чисел в целочисленной части (обязательный атрибут);

  • fraction − количество чисел в дробной части (обязательный атрибут);

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменные $value, $integer и $fraction для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.digits

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <digits integer="3" fraction="2" message="Value '$value' is out of bounds ($integer digits are expected in integer part and $fraction in fractional part)"/>
    </validators>
</textField>

Использование в Java коде:

DigitsValidator digitsValidator = beanLocator.getPrototype(DigitsValidator.NAME, 3, 2);
numberField.addValidator(digitsValidator);
FutureOrPresentValidator

Проверяет, что дата или время находится в будущем или настоящем. Валидатор не использует Groovy, поэтому нет параметров, которые вы можете передать в сообщение об ошибке. Поддерживаемые типы: java.util.Date, LocalDate, LocalDateTime, LocalTime, OffsetDateTime, OffsetTime.

Валидатор имеет следующие атрибуты:

  • checkSeconds − если установлено значение true, валидатор сравнивает дату или время с секундами и наносекундами. Значение по умолчанию − false;

  • message − сообщение, выводимое пользователю в случае ошибки валидации.

Ключи сообщения по умолчанию:

  • validation.constraints.futureOrPresent

Использование в XML-дескрипторе:

<dateField id="dateTimePropertyField" property="dateTimeProperty">
    <validators>
        <futureOrPresent checkSeconds="true"/>
    </validators>
</dateField>

Использование в Java коде:

FutureOrPresentValidator futureOrPresentValidator = beanLocator.getPrototype(FutureOrPresentValidator.NAME);
dateField.addValidator(futureOrPresentValidator);
FutureValidator

Проверяет, что дата или время находится в будущем. Валидатор не использует Groovy, поэтому нет параметров, которые вы можете передать в сообщение об ошибке. Поддерживаемые типы: java.util.Date, LocalDate, LocalDateTime, LocalTime, OffsetDateTime, OffsetTime.

Валидатор имеет следующие атрибуты:

  • checkSeconds − если установлено значение true, валидатор сравнивает дату или время с секундами и наносекундами. Значение по умолчанию − false;

  • message − сообщение, выводимое пользователю в случае ошибки валидации.

Ключи сообщения по умолчанию:

  • validation.constraints.future

Использование в XML-дескрипторе:

<timeField id="localTimeField" property="localTimeProperty" showSeconds="true">
    <validators>
        <future checkSeconds="true"/>
    </validators>
</timeField>

Использование в Java коде:

FutureValidator futureValidator = beanLocator.getPrototype(FutureValidator.NAME);
timeField.addValidator(futureValidator);
MaxValidator

Проверяет, что значение меньше или равно указанному максимальному значению. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer.

Валидатор имеет следующие атрибуты:

  • value − максимальное значение (обязательный атрибут);

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменные $value и $max для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.max

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <max value="20500" message="Value '$value' must be less than or equal to '$max'"/>
    </validators>
</textField>

Использование в Java коде:

MaxValidator maxValidator = beanLocator.getPrototype(MaxValidator.NAME, 20500);
numberField.addValidator(maxValidator);
MinValidator

Проверяет, что значение больше или равно указанному минимальному значению. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer.

Валидатор имеет следующие атрибуты:

  • value − минимальное значение (обязательный атрибут);

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменные $value и $min для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.min

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <min value="30" message="Value '$value' must be greater than or equal to '$min'"/>
    </validators>
</textField>

Использование в Java коде:

MinValidator minValidator = beanLocator.getPrototype(MinValidator.NAME, 30);
numberField.addValidator(minValidator);
NegativeOrZeroValidator

Проверяет, что значение меньше или равно 0. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer, Double, Float.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменную $value для форматированного вывода. Обратите внимание, что Float не имеет своего собственного типа данных и не будет отформатирован с пользовательской локалью.

Ключи сообщения по умолчанию:

  • validation.constraints.negativeOrZero

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <negativeOrZero message="Value '$value' must be less than or equal to 0"/>
    </validators>
</textField>

Использование в Java коде:

NegativeOrZeroValidator negativeOrZeroValidator = beanLocator.getPrototype(NegativeOrZeroValidator.NAME);
numberField.addValidator(negativeOrZeroValidator);
NegativeValidator

Проверяет, что значение строго меньше 0. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer, Double, Float.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменную $value для форматированного вывода. Обратите внимание, что Float не имеет своего собственного типа данных и не будет отформатирован с пользовательской локалью.

Ключи сообщения по умолчанию:

  • validation.constraints.negative

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <negative message="Value '$value' should be less than 0"/>
    </validators>
</textField>

Использование в Java коде:

NegativeValidator negativeValidator = beanLocator.getPrototype(NegativeValidator.NAME);
numberField.addValidator(negativeValidator);
NotBlankValidator

Проверяет, что значение содержит по крайней мере один символ без пробела. Валидатор не использует Groovy, поэтому нет параметров, которые вы можете передать в сообщение об ошибке. Поддерживаемый тип: String.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации.

Ключи сообщения по умолчанию:

  • validation.constraints.notBlank

Использование в XML-дескрипторе:

<textField id="textField" property="textProperty">
    <validators>
        <notBlank message="Value must contain at least one non-whitespace character"/>
    </validators>
</textField>

Использование в Java коде:

NotBlankValidator notBlankValidator = beanLocator.getPrototype(NotBlankValidator.NAME);
textField.addValidator(notBlankValidator);
NotEmptyValidator

Проверяет, что значение не пустое и не null. Поддерживаемые типы: Collection и String.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменную $value (только типа String) для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.notEmpty

Использование в XML-дескрипторе:

<textField id="textField" property="textProperty">
    <validators>
        <notBlank message="Value must contain at least one non-whitespace character"/>
    </validators>
</textField>

Использование в Java коде:

NotBlankValidator notBlankValidator = beanLocator.getPrototype(NotBlankValidator.NAME);
textField.addValidator(notBlankValidator);
NotNullValidator

Проверяет, что значение не null. Валидатор не использует Groovy, поэтому нет параметров, которые вы можете передать в сообщение об ошибке.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации.

Ключи сообщения по умолчанию:

  • validation.constraints.notNull

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <notNull/>
    </validators>
</textField>

Использование в Java коде:

NotNullValidator notNullValidator = beanLocator.getPrototype(NotNullValidator.NAME);
numberField.addValidator(notNullValidator);
PastOrPresentValidator

Проверяет, что дата или время находится в прошлом или настоящем. Валидатор не использует Groovy, поэтому нет параметров, которые вы можете передать в сообщение об ошибке. Поддерживаемые типы: java.util.Date, LocalDate, LocalDateTime, LocalTime, OffsetDateTime, OffsetTime.

Валидатор имеет следующие атрибуты:

  • checkSeconds − если установлено значение true, валидатор сравнивает дату или время с секундами и наносекундами. Значение по умолчанию − false;

  • message − сообщение, выводимое пользователю в случае ошибки валидации.

Ключи сообщения по умолчанию:

  • validation.constraints.pastOrPresent

Использование в XML-дескрипторе:

<dateField id="dateTimeField" property="dateTimeProperty">
    <validators>
        <pastOrPresent/>
    </validators>
</dateField>

Использование в Java коде:

PastOrPresentValidator pastOrPresentValidator = beanLocator.getPrototype(PastOrPresentValidator.NAME);
numberField.addValidator(pastOrPresentValidator);
PastValidator

Проверяет, что дата или время находится в прошлом. Валидатор не использует Groovy, поэтому нет параметров, которые вы можете передать в сообщение об ошибке. Поддерживаемые типы: java.util.Date, LocalDate, LocalDateTime, LocalTime, OffsetDateTime, OffsetTime.

Валидатор имеет следующие атрибуты:

  • checkSeconds − если установлено значение true, валидатор сравнивает дату или время с секундами и наносекундами. Значение по умолчанию − false;

  • message − сообщение, выводимое пользователю в случае ошибки валидации.

Ключи сообщения по умолчанию:

  • validation.constraints.past

Использование в XML-дескрипторе:

<dateField id="dateTimeField" property="dateTimeProperty">
    <validators>
        <pastOrPresent/>
    </validators>
</dateField>

Использование в Java коде:

PastOrPresentValidator pastOrPresentValidator = beanLocator.getPrototype(PastOrPresentValidator.NAME);
numberField.addValidator(pastOrPresentValidator);
PositiveOrZeroValidator

Проверяет, что значение больше или равно 0. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer, Double, Float.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменную $value для форматированного вывода. Обратите внимание, что Float не имеет своего собственного типа данных и не будет отформатирован с пользовательской локалью.

Ключи сообщения по умолчанию:

  • validation.constraints.positiveOrZero

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <positiveOrZero message="Value '$value' should be greater than or equal to '0'"/>
    </validators>
</textField>

Использование в Java коде:

PositiveOrZeroValidator positiveOrZeroValidator = beanLocator.getPrototype(PositiveOrZeroValidator.NAME);
numberField.addValidator(positiveOrZeroValidator);
PositiveValidator

Проверяет, что значение строго больше 0. Поддерживаемые типы: BigDecimal, BigInteger, Long, Integer, Double, Float.

Валидатор имеет следующие атрибуты:

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменную $value для форматированного вывода. Обратите внимание, что Float не имеет своего собственного типа данных и не будет отформатирован с пользовательской локалью.

Ключи сообщения по умолчанию:

  • validation.constraints.positive

Использование в XML-дескрипторе:

<textField id="numberField" property="numberProperty">
    <validators>
        <positive message="Value '$value' should be greater than '0'"/>
    </validators>
</textField>

Использование в Java коде:

PositiveValidator positiveValidator = beanLocator.getPrototype(PositiveValidator.NAME);
numberField.addValidator(positiveValidator);
RegexpValidator

Проверяет, что строковое значение соответствует указанному регулярному выражению. Поддерживаемый тип: String.

Валидатор имеет следующие атрибуты:

  • regexp − регулярное выражение для проверки соответствия (обязательный атрибут);

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменную $value для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.regexp

Использование в XML-дескрипторе:

<textField id="textField" property="textProperty">
    <validators>
        <regexp regexp="[a-z]*"/>
    </validators>
</textField>

Использование в Java коде:

RegexpValidator regexpValidator = beanLocator.getPrototype(RegexpValidator.NAME, "[a-z]*");
textField.addValidator(regexpValidator);
SizeValidator

Проверяет, что значение находится в определенном диапазоне. Поддерживаемые типы: Collection and String.

Валидатор имеет следующие атрибуты:

  • min − минимальное значение (включительно), не может быть меньше 0. Значение по умолчанию − 0;

  • max − максимальное значение (включительно), не может быть меньше 0. Значение по умолчанию − Integer.MAX_VALUE;

  • message − сообщение, выводимое пользователю в случае ошибки валидации. Это сообщение может содержать переменные $value (только для типа String), $min, $max для форматированного вывода.

Ключи сообщения по умолчанию:

  • validation.constraints.collectionSizeRange

  • validation.constraints.sizeRange

Использование в XML-дескрипторе:

<textField id="textField" property="textProperty">
    <validators>
        <size min="2" max="10" message="Value '$value' should be between '$min' and '$max'"/>
    </validators>
</textField>

<twinColumn id="twinColumn">
    <validators>
        <size min="2" max="4" message="Collection size must be between $min and $max"/>
    </validators>
</twinColumn>

Использование в Java коде:

SizeValidator sizeValidator = beanLocator.getPrototype(SizeValidator.NAME);
textField.addValidator(sizeValidator);