Javax 验证实现

Ric*_*ard 4 java validation annotations

我正在尝试为局部变量创建我的自定义注释,但我只是不明白注释是如何在代码中实现的,@NotNull或者@Null是如何在代码中实际实现的。我查看了实际文件,这是@NotNull

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {

    String message() default "{ javax.validation.constraints.NotNull.message }";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNull[] value();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我没有看到任何地方可以检查是否有东西null实际检查在哪里进行?

ini*_*mer 8

通常你需要提供用于验证的validatedBy 类

@Target(TYPE)
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {TicketPresenceValidator.class})
public @interface AtLeastOneTicket {
}


public class TicketPresenceValidator implements ConstraintValidator<AtLeastOneTicket, TicketInfo> {
 @Override
 public void initialize(TicketInfo constraintAnnotation) {
 }

 @Override
 public boolean isValid(TicketInfo ticketInfo, 
                        ConstraintValidatorContext context) {
    return ticketInfo.getSize() != 0;
 }
}
Run Code Online (Sandbox Code Playgroud)

对于内置约束(来自 javax.validation.* 包),如 NotNull 验证器由实现库提供。例如 Hibernate Validator 实现,这里是

NullValidator实现

然后约束和验证器在辅助类中链接在一起


Sab*_*han 6

实际检查在哪里进行?

如果您仔细查看 -javax.validation.constraints.@NotNull源代码(您已粘贴),@Constraint(validatedBy = { })则保留为空,即未指定哪个是实现类。这是因为像 -etc 这样的 javax 验证 jarvalidation-api-2.0.1.Final.jar基本上是一个 bean 验证标准(一组没有实现的接口、注释等)。这些约束的实现由像 hibernate、Oracle 等供应商提供。

此链接列出了三个标准,因此您应该知道您使用的是哪个版本的 bean 验证标准。

所以如果你有像 - 这样的实现 jars hibernate-validator-6.0.10.Final.jar,你也可以看到实现源代码,

/*
 * Hibernate Validator, declare and validate application constraints
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package org.hibernate.validator.internal.constraintvalidators.bv;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.NotNull;

/**
 * Validate that the object is not {@code null}.
 *
 * @author Emmanuel Bernard
 */
public class NotNullValidator implements ConstraintValidator<NotNull, Object> {

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
        return object != null;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您必须了解搜索/解析 bean 验证标准的实现是一项复杂的任务,请参阅 -javax.validation.ValidationProviderResolver如果开发人员使用 Spring Boot 等框架,则此过程已变得容易。

inigo 撇渣器的回答也做了这两件事 - 为您的自定义验证声明一个注释,实现实际验证并通过硬编码验证器类来解析验证器 - @Constraint(validatedBy = {TicketPresenceValidator.class})& 这使您免于复杂的验证实现搜索逻辑。

您必须了解的另一部分是您的验证器的类型,javax.validation.ConstraintValidator因此请阅读 javadoc 作为您需要提供给此接口的内容

其他链接参考,

创建自定义约束

使用 Bean Validation 2.0 创建您自己的约束