我想创建一个自定义验证器来验证名为description的字段。此字段的验证依赖于此bean中称为category的另一个字段 - 如果category是Other,则description不能为null或为空,如果category不是Other,则description必须为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)创建实现 - 这里我很困惑如何指定被比较的字段是Object的类别和描述字段?
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;
}
答案 0 :(得分:2)
由于验证涉及两个对象字段,因此需要将约束放在封闭类上。这是有道理的,因为现在您实际上正在验证(部分)对象,而不是单个字段。所以你必须这样做:
@CategoryDescription
public class InformationBean{
private String category;
private String description;
}
完成后,您现在可以实现isValid()
方法。如果验证器只适用于这个特定的类(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,因此您可以轻松获取类别和描述并实现正确的验证逻辑。这也是将注释放在类上的原因 - 否则您将无法访问这两个字段。如果注释放在字段上,则只能访问带注释字段的值。
如果您希望验证器适用于任何对象,您仍然可以使用您提供的验证器(使用Object
作为第二个通用参数)来执行此操作,但是您必须获取要访问的字段不同的方式(例如使用反射)。
编辑:要在课程上加上@CategoryDescription
约束,您需要在约束定义中将@Target(METHOD, FIELD, ANNOTATION_TYPE)
更改为@Target(TYPE)