4

JSR 303バリデーターとしてHibernateバリデーター(HV)を使用しています。ただし、JSR 303とHVの拡張機能の両方で、キーがマップに存在する必要がある、またはキーに対応するマップ値のみを検証するなどの制約を指定する注釈がないようです。

私のユースケースでは、Beanの他のプロパティがtrueに設定されている場合にのみ、一部のマップキーに有効な値が必要です。現在、私は偽のゲッターと@AssertTrueアノテーションを使用していましたが、これをもっとアノテーションベースにしたいと思っています。

4

1 に答える 1

3

キーがマップに存在する必要があるなど、制約を指定するための注釈はないようです。

これは、カスタム制約を実装することで解決できます。

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { ContainsKeyValidator.class })
public @interface ContainsKeys {
    String message() default "{com.acme.ContainsKey.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    String[] value() default {};
}

そして、このようなバリデーター:

public class ContainsKeysValidator implements ConstraintValidator<ContainsKeys, Map<?, ?>> {

    String[] requiredKeys;

    @Override
    public void initialize(ContainsKeys constraintAnnotation) {
        requiredKeys = constraintAnnotation.values();
    }

    @Override
    public boolean isValid(Map<?, ?> value, ConstraintValidatorContext context) {
        if( value == null ) {
            return true;
        }

        for( String requiredKey : requiredKeys ) {
            if( value.containsKey( requiredKey ) ) {
                return false;
            }
        }

        return true;
    }
}

私のユースケースでは、Beanの他のプロパティがtrueに設定されている場合にのみ、一部のマップキーに有効な値が必要です。

この要件では、クラスレベルの制約を実装できます。これにより、バリデーター実装のすべての属性を含む完全なBeanにアクセスできます。

于 2013-02-10T18:24:34.617 に答える