【问题标题】:how add custom validator for `javax.validation.constraints` annotation?如何为 `javax.validation.constraints` 注释添加自定义验证器?
【发布时间】:2019-02-21 09:20:36
【问题描述】:

我已经为Long 字段和@PastOrPresent 验证实现了验证

public class PastOrPresentValidator implements ConstraintValidator<PastOrPresent, Long>{
    @Override
    public boolean isValid(Long value, ConstraintValidatorContext context) {
        if (value == null) {
            return false;
        }
        return value <= System.currentTimeMillis();
    }
}

public class MyDto {
    @PastOrPresent
    Long timestamp;    
}

得到错误:

HV000030: No validator could be found for constraint 'javax.validation.constraints.PastOrPresent' validating type 'java.lang.Long'. Check configuration for 'push.dto.timestamp'

但是当我创建像 @PastOrPresentLong 这样的自定义注释并使用相同的验证器代码时,一切正常。

有没有办法为javax.validation.constraints 注解添加自定义验证器?

【问题讨论】:

  • 我认为你应该接受这个精彩的答案。

标签: java bean-validation spring-validator


【解决方案1】:

仅实现ConstraintValidator 接口不足以让您的新验证器正常工作。它应该以某种方式注册,以便 BeanValidation 提供者知道它。这可以通过 XML 完成(更多信息请参阅here):

<constraint-mappings
        xmlns="http://xmlns.jcp.org/xml/ns/validation/mapping"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/mapping
            http://xmlns.jcp.org/xml/ns/validation/mapping/validation-mapping-2.0.xsd"
        version="2.0">
    <!-- anything else -->
    <constraint-definition annotation="javax.validation.constraints.PastOrPresent">
        <validated-by include-existing-validators="true">
            <value>org.mycompany.PastOrPresentLongValidator</value>
        </validated-by>
    </constraint-definition>
</constraint-mappings>

如果您使用 Hibernate Validator 作为 BeanValidation 提供者,您还有另外两个选择 - 使用服务加载器或编程定义。 使用服务加载器是添加新验证器的最简单方法。您需要做的就是创建一个META-INF/services/javax.validation.ConstraintValidator 文件并向其中添加验证器的 FQCN。请参阅此post 中的“对非标准类使用标准约束”部分或doc 中的详细示例。 使用programmatic approach,您必须执行以下操作:

ConstraintMapping constraintMapping = configuration.createConstraintMapping();

constraintMapping
        .constraintDefinition( PastOrPresent.class )
        .validatedBy( PastOrPresentLongValidator.class );

然后将此约束映射添加到您的配置中并从中创建一个验证器:

Validator validator = configuration.addMapping( constraintMapping )
        .buildValidatorFactory()
        .getValidator();

但正如我之前提到的 - Service Loader 是最简单快捷的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    相关资源
    最近更新 更多