Validator

基本用法

Validator - 验证器 用来检查可视化组件中输入的值。

验证和输入检查是需要区分开来的,输入检查是说:假设一个文本组件(比如,TextField)的数据类型设置的不是字符串(这种情况可能出现在绑定实体属性或者手动设置控件的 datatype),那么这个组件会阻止用户输入不符合它定义的数据类型的值。当这个组件失去焦点时或者用户按了 回车,会显示验证错误信息。

但是,验证不会在输入同时或者失去焦点时马上反馈,而是会在组件的 validate() 方法调用的时候。也就是说这个组件(还有这个组件绑定的实体属性)暂时会包含一个可能并不符合验证规则的值。但是这没关系,因为需要验证的字段一般都会在编辑界面,所有的字段提交前会自动调用验证方法。如果组件不在一个编辑界面,那么这个组件的 validate() 方法需要在界面控制器显式的调用。

框架包含了一组最常用的验证器实现,可以直接在项目中使用:

在界面的 XML 描述中,组件的验证器可以在内部的 validators 元素中定义。可以通过 Jmix Studio 添加验证器。下面是给 TextField 组件添加验证器的例子:

validator

有些验证器在错误消息中使用了 Groovy 字符串。这样的话,可以给错误消息传递参数(比如,${value})。这些参数会考虑用户的 locale 配置。

每个验证器都是一个 Prototype Bean,如果希望在 Java 代码中使用验证器,需要通过 ApplicationContext 来获取:

PositiveValidator validator = applicationContext.getBean(PositiveValidator.class);

使用编程的方式给组件设置验证类,调用组件的 addValidator() 方法添加验证器的实例。

在界面控制器中编程式设置验证器类的示例:

textField.addValidator(applicationContext.getBean(PositiveValidator.class));

使用自定义验证器

可以使用自定义的 Java 类作为验证器,自定义类需要实现 Validator 接口。

创建验证邮编的验证器类:

@Component("ui_ZipValidator")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ZipValidator implements Validator<String> {
    @Override
    public void accept(String value) throws ValidationException {
        if (value != null && value.length() != 6)
            throw new ValidationException("Zip must be of 6 characters length");
    }
}

在界面的 XML 描述中,自定义的验证器可以在内部的 custom 元素中定义。

TextField 组件使用邮编验证器的示例:

<textField id="numberField22">
    <validators>
        <custom bean="ui_ZipValidator"/>
    </validators>
</textField>

在界面控制器中编程式设置验证器类的示例:

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

DecimalMaxValidator

检查值小于等于指定的最大值。支持的类型:BigDecimalBigIntegerLongInteger 以及使用当前 locale 表示 BigDecimalString 类型。

支持下列属性:

  • value - 最大值(必需);

  • inclusive - 当设置成 true 时,值应当小于或等于指定的最大值。设置成 false 时,值应当小于指定的最大值。默认值是 true

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${max} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.decimalMaxInclusive

  • validation.constraints.decimalMax

XML 描述中用法:

<textField id="numberField">
    <validators>
        <decimalMax value="1000"
                    inclusive="true"
                    message="Value ${value} cannot be greater than ${max}"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn1")
protected void onAddValidBtn1Click(Button.ClickEvent event) {
    DecimalMaxValidator maxValidator = applicationContext
            .getBean(DecimalMaxValidator.class, new BigDecimal(1000));
    numberField.addValidator(maxValidator);
}

DecimalMinValidator

检查值大于等于指定的最小值。支持的类型:BigDecimalBigIntegerLongInteger 以及使用当前 locale 表示 BigDecimalString 类型。

支持下列属性:

  • value - 最小值(必需);

  • inclusive - 当设置成 true 时,值应当大于或等于指定的最小值。设置成 false 时,值应当大于指定的最小值。默认值是 true

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${min} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.decimalMinInclusive

  • validation.constraints.decimalMin

XML 描述中用法:

<textField id="numberField2">
    <validators>
        <decimalMin value="100"
                    inclusive="false"
                    message="Value ${value} cannot be less than ${min}"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField2;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn2")
protected void onAddValidBtn2Click(Button.ClickEvent event) {
    DecimalMinValidator minValidator = applicationContext
            .getBean(DecimalMinValidator.class, new BigDecimal(100));
    numberField2.addValidator(minValidator);
}

DigitsValidator

检查值是一个指定范围内的数字。支持的类型:BigDecimalBigIntegerLongInteger 以及使用当前 locale 表示 BigDecimalString 类型。

支持下列属性:

  • integer - 整数部分数字的个数(必需);

  • fraction - 小数部分数字的个数(必需);

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${integer}${fraction} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.digits

XML 描述中用法:

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

Java 代码用法:

@Autowired
protected TextField numberField3;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn3")
protected void onAddValidBtn3Click(Button.ClickEvent event) {
    DigitsValidator digitsValidator = applicationContext
            .getBean(DigitsValidator.class, 3, 2);
    numberField3.addValidator(digitsValidator);
}

DoubleMaxValidator

检查值是否小于或等于指定的最大值。支持的类型:Double 以及使用当前 locale 表示 Double 值的 String 类型。

支持下列属性:

  • value - 最大值(必需);

  • inclusive - 当设置成 true 时,值应当小于或等于指定的最大值。设置成 false 时,值应当小于指定的最大值。默认值是 true

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${max} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.decimalMaxInclusive

  • validation.constraints.decimalMax

XML 描述中用法:

<textField id="numberField4">
    <validators>
        <doubleMax value="1000"
                   inclusive="false"
                   message="Value ${value} cannot be greater than ${max}"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField4;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn4")
protected void onAddValidBtn4Click(Button.ClickEvent event) {
    DoubleMaxValidator maxValidator = applicationContext
            .getBean(DoubleMaxValidator.class, Double.valueOf(1000));
    numberField4.addValidator(maxValidator);
}

DoubleMinValidator

检查值大于等于指定的最小值。支持的类型:Double 以及使用当前 locale 表示 Double 值的 String 类型。

支持下列属性:

  • value - 最小值(必需);

  • inclusive - 当设置成 true 时,值应当大于或等于指定的最小值。设置成 false 时,值应当大于指定的最小值。默认值是 true

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${min} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.decimalMinInclusive

  • validation.constraints.decimalMin

XML 描述中用法:

<textField id="numberField5">
    <validators>
        <doubleMin value="100"
                   inclusive="false"
                   message="Value ${value} cannot be less than ${max}"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField5;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn5")
protected void onAddValidBtn5Click(Button.ClickEvent event) {
    DoubleMinValidator minValidator = applicationContext
            .getBean(DoubleMinValidator.class, Double.valueOf(100));
    numberField5.addValidator(minValidator);
}

EmailValidator

检查 String 类型的值是否是电子邮件地址或者包含多个用英文分号、逗号分隔的电子邮件地址。支持类型:String

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.invalidEmail

XML 描述中用法:

<textField id="numberField23">
    <validators>
        <email message="Invalid email address"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField23;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn23")
protected void onAddValidBtn23Click(Button.ClickEvent event) {
    EmailValidator emailValidator = applicationContext
            .getBean(EmailValidator.class);
    numberField23.addValidator(emailValidator);
}

FutureOrPresentValidator

检查日期或时间是否是将来时间或者当前时间。不使用 Groovy 字符串,所以没有参数可用于消息格式化。支持的类型:java.util.DateLocalDateLocalDateTimeLocalTimeOffsetDateTimeOffsetTime

支持下列属性:

  • checkSeconds - 当设置成 true 时,验证器需要使用秒和毫秒比较日期或者时间。默认值是 false

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.constraints.futureOrPresent

XML 描述中用法:

<dateField id="dateTimeField">
    <validators>
        <futureOrPresent checkSeconds="true"/>
    </validators>
</dateField>

Java 代码用法:

@Autowired
protected DateField dateTimeField;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn6")
protected void onAddValidBtn6Click(Button.ClickEvent event) {
    FutureOrPresentValidator futureOrPresentValidator = applicationContext
            .getBean(FutureOrPresentValidator.class);
    dateTimeField.addValidator(futureOrPresentValidator);
}

FutureValidator

检查日期或时间是否是将来时间。不使用 Groovy 字符串,所以没有参数可用于消息格式化。支持的类型:java.util.DateLocalDateLocalDateTimeLocalTimeOffsetDateTimeOffsetTime

支持下列属性:

  • checkSeconds - 当设置成 true 时,验证器需要使用秒和毫秒比较日期或者时间。默认值是 false

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.constraints.future

XML 描述中用法:

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

Java 代码用法:

@Autowired
protected TimeField localTimeField;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn7")
protected void onAddValidBtn7Click(Button.ClickEvent event) {
    FutureValidator futureValidator = applicationContext
            .getBean(FutureValidator.class);
    localTimeField.addValidator(futureValidator);
}

MaxValidator

检查值是否小于或等于指定的最大值。支持的类型:BigDecimalBigIntegerLongInteger

支持下列属性:

  • value - 最大值(必需);

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${max} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.max

XML 描述中用法:

<textField id="numberField8">
    <validators>
        <max value="20500"
             message="Value ${value} must be less than or equal to ${max}"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField8;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn8")
protected void onAddValidBtn8Click(Button.ClickEvent event) {
    MaxValidator maxValidator = applicationContext
            .getBean(MaxValidator.class, 20500);
    numberField8.addValidator(maxValidator);
}

MinValidator

检查值大于等于指定的最小值。支持的类型:BigDecimalBigIntegerLongInteger

支持下列属性:

  • value - 最小值(必需);

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}${min} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.min

XML 描述中用法:

<textField id="numberField9">
    <validators>
        <min value="30"
             message="Value ${value} must be greater than or equal to ${min}"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField9;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn9")
protected void onAddValidBtn9Click(Button.ClickEvent event) {
    MinValidator minValidator = applicationContext
            .getBean(MinValidator.class, 30);
    numberField9.addValidator(minValidator);
}

NegativeOrZeroValidator

检查值小于等于 0。支持的类型:BigDecimalBigIntegerLongIntegerDoubleFloat

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value} 关键字,用于格式化输出。注意,Float 并没有它自己的数据类型,不会使用用户的 locale 进行格式化。

默认消息键值:

  • validation.constraints.negativeOrZero

XML 描述中用法:

<textField id="numberField10">
    <validators>
        <negativeOrZero message="Value ${value} must be less than or equal to 0"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField10;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn10")
protected void onAddValidBtn10Click(Button.ClickEvent event) {
    NegativeOrZeroValidator negativeOrZeroValidator = applicationContext
            .getBean(NegativeOrZeroValidator.class);
    numberField10.addValidator(negativeOrZeroValidator);
}

NegativeValidator

检查值严格小于 0。支持的类型:BigDecimalBigIntegerLongIntegerDoubleFloat

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value} 关键字,用于格式化输出。注意,Float 并没有它自己的数据类型,不会使用用户的 locale 进行格式化。

默认消息键值:

  • validation.constraints.negative

XML 描述中用法:

<textField id="numberField11">
    <validators>
        <negativeOrZero message="Value ${value} must be less than 0"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField11;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn11")
protected void onAddValidBtn11Click(Button.ClickEvent event) {
    NegativeValidator negativeValidator = applicationContext
            .getBean(NegativeValidator.class);
    numberField11.addValidator(negativeValidator);
}

NotBlankValidator

检查值至少包含一个非空字符。不使用 Groovy 字符串,所以没有参数可用于消息格式化。支持的类型:String

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.constraints.notBlank

XML 描述中用法:

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

Java 代码用法:

@Autowired
protected TextField numberField12;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn12")
protected void onAddValidBtn12Click(Button.ClickEvent event) {
    NotBlankValidator notBlankValidator = applicationContext
            .getBean(NotBlankValidator.class);
    numberField11.addValidator(notBlankValidator);
}

NotEmptyValidator

检查值不是 null 也非空。支持的类型:CollectionString

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value} 关键字,用于格式化输出,只对 String 类型有效。

默认消息键值:

  • validation.constraints.notEmpty

XML 描述中用法:

<textField id="numberField13">
    <validators>
        <notEmpty/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField13;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn13")
protected void onAddValidBtn13Click(Button.ClickEvent event) {
    NotEmptyValidator notEmptyValidator = applicationContext
            .getBean(NotEmptyValidator.class);
    numberField13.addValidator(notEmptyValidator);
}

NotNullValidator

检查值不是 null。不使用 Groovy 字符串,所以没有参数可用于消息格式化。

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.constraints.notNull

XML 描述中用法:

<textField id="numberField14">
    <validators>
        <notNull/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField14;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn14")
protected void onAddValidBtn14Click(Button.ClickEvent event) {
    NotNullValidator notNullValidator = applicationContext
            .getBean(NotNullValidator.class);
    numberField14.addValidator(notNullValidator);
}

PastOrPresentValidator

检查日期或时间是过去时间或者当前时间。不使用 Groovy 字符串,所以没有参数可用于消息格式化。支持的类型:java.util.DateLocalDateLocalDateTimeLocalTimeOffsetDateTimeOffsetTime

支持下列属性:

  • checkSeconds - 当设置为 ture 时,验证器需要使用秒和毫秒比较日期或者时间。默认值是 false

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.constraints.pastOrPresent

XML 描述中用法:

<dateField id="dateField">
    <validators>
        <pastOrPresent/>
    </validators>
</dateField>

Java 代码用法:

@Autowired
protected DateField dateField;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn15")
protected void onAddValidBtn15Click(Button.ClickEvent event) {
    PastOrPresentValidator pastOrPresentValidator = applicationContext
            .getBean(PastOrPresentValidator.class);
    dateField.addValidator(pastOrPresentValidator);
}

PastValidator

检查日期或时间是过去时间。不使用 Groovy 字符串,所以没有参数可用于消息格式化。支持的类型:java.util.DateLocalDateLocalDateTimeLocalTimeOffsetDateTimeOffsetTime

支持下列属性:

  • checkSeconds - 当设置为 ture 时,验证器需要使用秒和毫秒比较日期或者时间。默认值是 false

  • message - 自定义的消息,在验证失败时展示。

默认消息键值:

  • validation.constraints.past

XML 描述中用法:

<dateField id="dateField16">
    <validators>
        <past/>
    </validators>
</dateField>

Java 代码用法:

@Autowired
protected DateField dateField16;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn16")
protected void onAddValidBtn16Click(Button.ClickEvent event) {
    PastValidator pastValidator = applicationContext
            .getBean(PastValidator.class);
    dateField16.addValidator(pastValidator);
}

PositiveOrZeroValidator

检查值大于等于 0。支持的类型:BigDecimalBigIntegerLongIntegerDoubleFloat

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value} 关键字,用于格式化输出。注意,Float 并没有它自己的数据类型,不会使用用户的 locale 进行格式化。

默认消息键值:

  • validation.constraints.positiveOrZero

XML 描述中用法:

<textField id="numberField17">
    <validators>
        <positiveOrZero message="Value ${value} should be greater than or equal to '0'"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField17;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn17")
protected void onAddValidBtn17Click(Button.ClickEvent event) {
    PositiveOrZeroValidator positiveOrZeroValidator = applicationContext
            .getBean(PositiveOrZeroValidator.class);
    numberField17.addValidator(positiveOrZeroValidator);
}

PositiveValidator

检查值严格大于 0。支持的类型:BigDecimalBigIntegerLongIntegerDoubleFloat

支持下列属性:

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value} 关键字,用于格式化输出。注意,Float 并没有它自己的数据类型,不会使用用户的 locale 进行格式化。

默认消息键值:

  • validation.constraints.positive

XML 描述中用法:

<textField id="numberField18">
    <validators>
        <positive message="Value ${value} should be greater than '0'"/>
    </validators>
</textField>

Java 代码用法:

@Autowired
protected TextField numberField18;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn18")
protected void onAddValidBtn18Click(Button.ClickEvent event) {
    PositiveValidator positiveValidator = applicationContext
            .getBean(PositiveValidator.class);
    numberField18.addValidator(positiveValidator);
}

RegexpValidator

检查 String 的值是否能匹配提供的正则表达式。支持的类型:String

支持下列属性:

  • regexp - 一个用于匹配的正则表达式(必需);

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.regexp

XML 描述中用法:

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

Java 代码用法:

@Autowired
protected TextField numberField18;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn19")
protected void onAddValidBtn19Click(Button.ClickEvent event) {
    RegexpValidator regexpValidator = applicationContext
            .getBean(RegexpValidator.class);
    numberField19.addValidator(regexpValidator);
}

SizeValidator

检查值在一定范围内。支持的类型:CollectionString

支持下列属性:

  • min - 最小值(含),不能小于 0。默认值是 0;

  • max - 最大值(含),不能小于 0。默认值是 Integer.MAX_VALUE

  • message - 自定义的消息,在验证失败时展示。该消息可以包含 ${value}(只对 String 类型有效),${min}${max} 关键字,用于格式化输出。

默认消息键值:

  • validation.constraints.collectionSizeRange

  • validation.constraints.sizeRange

XML 描述中用法:

<textField id="numberField20">
    <validators>
        <size max="10"
              min="2"
              message="Value ${value} should be between ${min} and ${max}"/>
    </validators>
</textField>
<twinColumn id="twinColumn" rows="4">
    <validators>
        <size max="4"
              min="2"
              message="Collection size must be between ${min} and ${max}"/>
    </validators>
</twinColumn>

Java 代码用法:

@Autowired
protected TextField numberField20;

@Autowired
protected ApplicationContext applicationContext;

@Subscribe("addValidBtn20")
protected void onAddValidBtn20Click(Button.ClickEvent event) {
    SizeValidator sizeValidator = applicationContext
            .getBean(SizeValidator.class);
    numberField20.addValidator(sizeValidator);
}