在注释上使用 validator.getConstraintsForClass 会产生与使用包含注释的 getConstraintsForProperty 不同的结果

问题描述 投票:0回答:1

我有许多 Java Annotation 类。

我的项目的开发者/消费者将在其 POJO 内的字段上使用这些注释来描述每个字段。

这些注释之间的关系示例:

@CustomString
->
@CustomPassword

为什么当我尝试使用

@CustomPassword
获取
validator.getConstraintsForClass
的约束时,
min
不包含
CustomPassword
中指定的值,即
10

我想用:

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

要覆盖该值,因为我希望开发人员能够创建自己的注释类,这些注释类位于

CustomPassword
之上,并且可能提供自己的覆盖。

@CustomString
设置
@Size
min
max
约束:

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
的引用,并尝试覆盖
min
中的
@CustomString

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);

constraintDescriptors
里面的
BeanDescriptor
仍然有
min
0
,难道不应该被
min
里面的
CustomPassword
覆盖并设置为
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)
java validation annotations constraints bean-validation
1个回答
0
投票

问题是您正在尝试查看约束注释本身的 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
的实例一样,此时验证器将
CustomString
视为类级约束,并且没有任何
OverridesAttribute
来自考虑
CustomPassword
,因为 beans 不会覆盖任何约束属性。

© www.soinside.com 2019 - 2024. All rights reserved.