1

カスタム制約を記述する場合、1 つのバリデーター実装で複数のアノテーションを検証することができます。たとえば、さまざまな @size 注釈を規定するいくつかの注釈がありますが、それらすべてが、いくつかのグローバル チェックを行う同じバリデータ クラスを指すようにします。つまり、すべてが特定の正規表現に一致する必要があります。私が見る限り、実装は 1 つのアノテーション タイプを取り込んでいます。

1 つの注釈

@Target( { METHOD, FIELD, ANNOTATION_TYPE, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {UCNValidator.class})
@Documented
@Size(min = 9, max = 9, message = "{exactlength}")
public @interface UCN {

    String message() default "{invalidFormat}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String fieldName() default "ucn";

}

バリデーター

public class UCNValidator implements ConstraintValidator<UCN, String>
{

    private String pattern = "[a-zA-Z].*";
    private String fieldName;

    @Override
    public void initialize( UCN constraintAnnotation )
    {
        this.fieldName = constraintAnnotation.fieldName();
    }

    @Override
    public boolean isValid( String value, ConstraintValidatorContext constraintValidatorContext )
    {

        if ( value != null )
        {
            if ( !value.matches(pattern) )
            {
                //do some stuff
                return false;
            }

        }

        return true;

    }
4

1 に答える 1

0

プロパティの1つを検証するときに、オブジェクトから他の値にアクセスする方法はないようです。私が使用する解決策は、クラスに注釈を付けることです。そうすると、バリデーターがオブジェクト全体を取得して検証し、検証を実行するために必要な情報だけにアクセスできます。

これは、オブジェクトの2つの異なるプロパティを相互に比較するために作成したものです。

@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = LessThanValidator.class)
@Documented
public @interface LessThan {

    String message() default "{com.bullethq.constraints.LessThan}";

    String bigValueProperty();

    String littleValueProperty();

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

その場合、バリデータークラスは次のとおりです。

public class LessThanValidator implements ConstraintValidator<LessThan, Object> {

    private LessThan constraint;

    public void initialize(LessThan constraintAnnotation) {
        constraint = constraintAnnotation;
    }

    public boolean isValid(Object object, ConstraintValidatorContext cvc) {
        Object bigValue = getValue(object, constraint.bigValueProperty());
        Object littleValue = getValue(object, constraint.littleValueProperty());

        // If one of the values is null, then we do not perform validation.
        if (bigValue == null || littleValue == null) {
            return true;
        }

        if (bigValue instanceof Comparable && littleValue instanceof Comparable) {
            boolean valid = ((Comparable<Object>) bigValue).compareTo(littleValue) > 0;
            if (!valid) {
                // If the values are not valid, then build a custom violations which has the correct path in it.
                cvc.buildConstraintViolationWithTemplate(cvc.getDefaultConstraintMessageTemplate())
                        .addNode(constraint.littleValueProperty())
                        .addConstraintViolation().disableDefaultConstraintViolation();
            }
            return valid;
        }
        throw new IllegalArgumentException("Properties " + constraint.bigValueProperty() + " and " + constraint.littleValueProperty() + " both need to be comparable in " + object.getClass());
    }
}

getValue()メソッドは、リフレクションを使用してオブジェクトから値を取得する静的メソッドです。

于 2012-04-13T12:38:20.977 に答える