Javax验证实现

时间:2016-04-07 13:23:31

标签: 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();
    }
}

但是,我不会在任何地方看到它检查某些内容是否null实际检查在哪里?

2 个答案:

答案 0 :(得分:1)

通常您需要提供用于验证的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;
 }
}

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

NullValidator实施

然后在helper class

中将约束和验证器链接在一起

答案 1 :(得分:1)

  

实际检查在哪里进行?

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

This link列出了三个标准,因此您应该知道所使用的bean验证标准的版本。

因此,如果您有--hibernate-validator-6.0.10.Final.jar之类的实现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;
    }
}

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

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

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

其他要引用的链接,

Creating custom constraints

Create Your Own Constraints With Bean Validation 2.0