如何将继承应用于带约束的javax验证

如何将继承应用于带约束的javax验证,java,validation,customvalidator,Java,Validation,Customvalidator,当使用来自javax验证的自定义约束时,我们会遇到以下问题。我们有多种类型的ID,希望通过几个参数进行验证。在这里,我们希望应用继承,从而删除大量重复的代码。然而,混合继承和注释是困难的,因此我们使用了验证器的继承: @Constraint(validatedBy = { FirstIdValidator.class }) @Target({TYPE, FIELD, PARAMETER, METHOD, CONSTRUCTOR, TYPE_PARAMETER, TYPE_USE}) @Reten

当使用来自javax验证的自定义约束时,我们会遇到以下问题。我们有多种类型的ID,希望通过几个参数进行验证。在这里,我们希望应用继承,从而删除大量重复的代码。然而,混合继承和注释是困难的,因此我们使用了验证器的继承:

@Constraint(validatedBy = { FirstIdValidator.class })
@Target({TYPE, FIELD, PARAMETER, METHOD, CONSTRUCTOR, TYPE_PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface FirstId {
   boolean isOptional;
   boolean allowFormatted;

   //Other fields
}

@Constraint(validatedBy = { SecondIdValidator.class })
@Target({TYPE, FIELD, PARAMETER, METHOD, CONSTRUCTOR, TYPE_PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface SecondId {
   boolean isOptional;
   boolean allowFormatted;

   //Other fields
}

public class FirstIdValidator extends IdValidator<FirstId> {

    @Override
    public void initialize(final FirstId constraintAnnotation) {
        initialize(
                "style first id formatted",
                "style first id unformatted",
                constraintAnnotation.allowFormatted(),
                constraintAnnotation.isOptional()
        );
    }
}

public class SecondIdValidator extends IdValidator<SecondId> {

    @Override
    public void initialize(final SecondId constraintAnnotation) {
        initialize(
                "style second id formatted",
                "style SecondId id unformatted",
                constraintAnnotation.allowFormatted(),
                constraintAnnotation.isOptional()
        );
    }
}

abstract class IdValidator<A extends Annotation> implements javax.validation.ConstraintValidator<A, CharSequence> {

    private String idRegex;
    private String formattedIdRegex;
    private boolean allowFormatted;
    private boolean isOptional;

    void initialize(final String idRegex, final String formattedIdRegex, final boolean allowFormatted, final boolean isOptional) {
        this.idRegex = idRegex;
        this.formattedIdRegex = formattedIdRegex;
        this.allowFormatted = allowFormatted;
        this.isOptional = isOptional;
    }

    @Override
    protected boolean isValid(final CharSequence id, javax.validation.ConstraintValidatorContext context) {
       //Logic to check if it is valid
    }
}
@Constraint(validatedBy={FirstIdValidator.class})
@目标({类型、字段、参数、方法、构造函数、类型\参数、类型\使用})
@保留(运行时)
public@interface FirstId{
布尔等参;
布尔允许格式;
//其他领域
}
@约束(validatedBy={SecondIdValidator.class})
@目标({类型、字段、参数、方法、构造函数、类型\参数、类型\使用})
@保留(运行时)
public@interface SecondId{
布尔等参;
布尔允许格式;
//其他领域
}
公共类FirstIdValidator扩展IdValidator{
@凌驾
公共无效初始化(最终第一个ID约束){
初始化(
“样式首个id已格式化”,
“样式首个id未格式化”,
ConstraintAnotation.allowFormatted(),
constraintanotation.isOptional()
);
}
}
公共类SecondIdValidator扩展IdValidator{
@凌驾
公共void初始化(最终第二个ID ConstraintAnotation){
初始化(
“样式第二个id已格式化”,
“样式第二个id未格式化”,
ConstraintAnotation.allowFormatted(),
constraintanotation.isOptional()
);
}
}
抽象类IdValidator实现javax.validation.ConstraintValidator{
私有字符串idRegex;
私有字符串格式化的IDregex;
私有布尔允许格式;
私有布尔等参;
无效初始化(最终字符串idRegex、最终字符串格式化idRegex、最终布尔allowFormatted、最终布尔等可选){
this.idRegex=idRegex;
this.formattedIdRegex=formattedIdRegex;
this.allowFormatted=allowFormatted;
this.isOptional=isOptional;
}
@凌驾
受保护的布尔值isValid(最终字符序列id,javax.validation.ConstraintValidatorContext上下文){
//检查其是否有效的逻辑
}
}

这不是一个很好的解决方案,导致多个类没有做任何有趣的事情。对于不同的场景,将其重写为多个注释不是一个选项,因为有太多的注释。这是解决此问题的正确方法还是有更好的方法解决此问题?

对于每个特定用例,我不认为有多个验证器存在问题。另外,检查字段
allowFormatted
isOptional
的顺序,对于
initialize
和超类的调用者来说,这似乎是不同的;-)问题是,现在有许多通用代码可以通过使用抽象超类(即继承)来解决,但也可能以不同的方式解决。对于您的评论,我犯了一个简化复制粘贴的错误,但现在更正了:-)。