2

我创建了我的第一个自定义验证注释,其中验证器类作为内部类(我发现它安排得很好)。它看起来像这样:

@Target( { ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {OneOfGroupNotNull.Validator.class})
@Documented
public @interface OneOfGroupNotNull {

    // custom annotation properties
    String[] fields();

    // required by JSR-303
    String message() default "One of group must be not null. {fields}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    public class Validator implements ConstraintValidator<OneOfGroupNotNull, Object> {

        private String[] fields;

        @Override
        public boolean isValid(Object bean, ConstraintValidatorContext cvc) {

            int countNotNull = 0;

            for (String field : fields) {
                try {
                    String property = BeanUtils.getProperty(bean, field);
                    if (property != null) {
                        countNotNull++;
                    }
                } catch (Exception ex) {
                    throw new RuntimeException("Validation for field " + field + " of type " + bean.getClass()+ " raised exception.", ex);
                }
            }

            return countNotNull == 1;
        }

        @Override
        public void initialize(OneOfGroupNotNull a) {
            fields = a.fields();
        }
    }
}

使用此验证器注释的 bean 类可能如下所示:

@OneOfGroupNotNull(fields = {"a", "b", "c"})
public interface MyBean {
    String getA();
    Rarity getB();
    Boolean getC();
}

问题是我找不到格式化字符串数组“字段”的方法。它只是采用 to string 方法,结果如下:其中一个组必须不为空。[Ljava.lang.String;@157d954

4

2 回答 2

2

如果您将类型fields从更改为String[]String则带有字段名称的消息将正确显示。要获得约束中的字段名称,只需split()使用逗号即可。

另一种选择是在约束内生成自定义消息,如下所示:

cvc.disableDefaultConstraintViolation();
cvc.buildConstraintViolationWithTemplate("error message")
    .addNode("field name with error")
    .addConstraintViolation();
于 2012-11-12T14:37:56.457 回答
0

您正在使用哪种 Bean Validation 实现?如果您使用的是 Hibernate Validator 4.3,这应该可以正常工作。另请参阅https://hibernate.onjira.com/browse/HV-506

作为一种解决方法,为什么不使用List?那里默认的toString更明智。

于 2012-11-12T14:53:39.290 回答