2012-04-13 7 views
1

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

    } 
+0

これは、いずれの場合でも、最善の方法ではないと判断しました。共通の検証機能のために、私はすべてのバリデーターが使用する共通のメソッドを書くことができます。 – andyfinch

答えて

0

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

ここで私はお互いに対してオブジェクトの二つの異なる性質を比較するために書いたのです。そして、バリデータクラスがある

@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()メソッドは、単に静的なメソッドですが、リフレクションを使用してオブジェクトから値を取得します。

+0

'getValue'のコードを投稿することができればずっと助けになるでしょう – dakait

関連する問題