java 对注解使用validator.getConstraintsForClass与使用包含注解的getConstraintsForProperty会产生不同的结果

9rygscc1  于 2023-11-15  发布在  Java
关注(0)|答案(1)|浏览(108)

我有一些Java Annotation类。
这个想法是,我的项目的开发人员/消费者将在他们的POJO中的字段上使用这些注解,以便描述每个字段。
这些注解之间的关系示例:@CustomString-> @CustomPassword
为什么当我尝试使用validator.getConstraintsForClass获取@CustomPassword上的约束时,min不包含CustomPassword内部指定的值,即10
我想用途:

@OverridesAttribute(constraint = CustomString.class, name = "min")
int min() default 10;

字符串
因为我希望开发人员能够创建他们自己的注解类,这些注解类位于CustomPassword之上,并且可能提供他们自己的覆盖。
@CustomString设置@Sizeminmax约束:

import java.lang.annotation.*;
import javax.validation.Constraint;
import javax.validation.OverridesAttribute;
import javax.validation.Payload;
import javax.validation.constraints.Size;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Size
@Constraint(validatedBy = {})
public @interface CustomString {

  @OverridesAttribute(constraint = Size.class, name = "min")
  int min() default 0;

  @OverridesAttribute(constraint = Size.class, name = "max")
  int max() default Integer.MAX_VALUE;

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

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

  String message() default "{org.example.annotation.base.string}";
}


@CustomPassword,它包含对@CustomString的引用,并试图覆盖来自@CustomStringmin

import org.ecample.annotation.base.CustomString;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.OverridesAttribute;
import javax.validation.Payload;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@CustomString
@Constraint(validatedBy = {})
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface CustomPassword {

  @OverridesAttribute(constraint = CustomString.class, name = "min")
  int min() default 10;

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

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

  String message() default "{org.example.annotation.extended.password}";
}


为什么我跑步的时候:

Class<?> klass = CustomPassword.class;
Validator validator =
        Validation.byDefaultProvider()
            .configure()
            .messageInterpolator(new ParameterMessageInterpolator())
            .buildValidatorFactory().getValidator();
BeanDescriptor beanDescriptor = validator.getConstraintsForClass(klass);


BeanDescriptor内部的constraintDescriptors仍然有0min,它不应该被CustomPassword内部的min覆盖并设置为10吗?

((BeanDescriptorImpl)beanDescriptor).constraintDescriptors.iterator().next().annotationDescriptor

@c.c.c.m.t.a.b.CustomString(groups=[Ljava.lang.Class;@3d9f0a5, max=2147483647, message={org.example.annotation.base.string}, min=0, payload=[Ljava.lang.Class;@1953bc95)

zf9nrax1

zf9nrax11#

问题是你试图查看约束注解本身的bean描述符。Validator#getConstraintsForClass(..)旨在为bean提供元数据。如果你尝试这样的操作:

public class ConstrainedBean {
    @CustomPassword
    public String password;
}
//...

BeanDescriptor beanDescriptor = validator.getConstraintsForClass( ConstrainedBean.class );

字符串
这个bean描述符将包含一个受约束的属性,您将能够获得预期的10,首先通过constraintDescriptor#composingConstraints导航到CustomString,然后到达Size
当你传递CustomPassword.class时,你会得到一个元数据,就好像你要验证CustomPassword.class的示例一样,在这一点上,validator将CustomString视为类级别的约束,而不考虑来自CustomPasswordOverridesAttribute,因为bean不覆盖任何约束属性。

相关问题