比较 bean 的两个字段的自定义验证器

Custom validator that compares two fields of a bean

我想创建一个自定义验证器来验证一个名为 description 的字段。此字段的验证取决于此 bean 中称为类别的另一个字段 - 如果类别为其他,则说明不能为 null 或为空,如果类别不是其他,则说明必须为 null 或为空。 我以前没有写过自定义验证器,希望得到任何帮助。 这是我到目前为止所拥有的 (1) 创建@interface

import java.lang.annotation.Documented;
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.Payload;
@Target(METHOD, FIELD, ANNOTATION_TYPE )
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=CategoryDescriptionValidator.class)
public @interface CategoryDescription {
String message() default "{description should be empty when category is not other}";
Class<?>[] groups() default {};
}

(2) 创建实现 - 在这里我很困惑如何指定被比较的字段是对象的类别和描述字段?

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class CategoryDescriptionValidator implements ConstraintValidator<CategoryDescription,Object>{
@Override
public void initialize(CategoryDescription arg0) {
    // TODO Auto-generated method stub

}
@Override
public boolean isValid(Object arg0, ConstraintValidatorContext arg1) {
    // TODO Auto-generated method stub
    return false;
}

}

(3) 在我的 bean(InformationBean) 中,我应该只执行以下操作吗?

 public class InformationBean{
 private String category;
 @CategoryDescriptionValidator 
 private String description;
}

由于验证涉及两个对象字段,您需要将约束放在封闭的 class 上。这是有道理的,因为现在您实际上是在验证(部分)对象,而不是单个字段。所以你必须这样做:

@CategoryDescription
public class InformationBean{
 private String category; 
 private String description;
}

完成后,您现在可以实施 isValid() 方法。如果验证器只适用于这个特定的 class (InformationBean),您可以像这样参数化验证器:

public class CategoryDescriptionValidator implements ConstraintValidator<CategoryDescription ,InformationBean>{
  @Override
  public void initialize(CategoryDescription arg0) {
   // ...
  }

  @Override
  public boolean isValid(InformationBean arg0, ConstraintValidatorContext arg1) {
    // validation code here 
  }
}

如您所见,isValid() 的第一个参数是您的 bean,因此您可以轻松获取类别和描述并实施适当的验证逻辑。这也是将注释放在 class 上的原因 - 否则您将无法访问这两个字段。如果注释放在字段上,您只能访问注释字段的值。

如果您希望验证器适用于任何对象,您仍然可以使用您提供的验证器来执行此操作(使用 Object 作为第二个通用参数),但是您必须将字段设置为以不同的方式访问(例如使用反射)。

编辑:要将 @CategoryDescription 约束放在 class 上,您需要在约束定义

中将 @Target(METHOD, FIELD, ANNOTATION_TYPE) 更改为 @Target(TYPE)