2012-05-23 5 views
14

JSR-303の@Validアノテーションに問題があります。 annotationが通常のリストまたはやセットのため正常に動作しますが、私はリストが含まれている地図を検証しようとしています。この場合、すなわちマップ内のコレクションを検証する方法

@Valid 
HashMap<String, ArrayList<Object1>> map; 

Object1クラスのインスタンスが検証されません。すべてのオブジェクトを反復処理せずに手動で検証することなく、再帰的に行う便利な方法はありますか?

答えて

13

この仕様では、マップ値がそれ自体のリストである場合の検証動作は指定されていません。 JSR 303 specificationから

:イテレータによって提供される各オブジェクトが検証され

。マップの場合、各Map.Entryの値 が検証されます(キーは検証されません)。

あなたのケースの値は@Validアノテーションを持たないリストなので、処理されません。これを回避するには、次のいずれかを実行します。

含まれているリストを別のBeanにラップし、注釈処理を強制的にリストに適用します。

public class ListHolder<T extends Iterable> { 
    @Valid 
    public T wrappedList; 
} 

また、custom validatorを書き込んで、複雑なマップを処理することもできます。

@Target({ METHOD, FIELD, ANNOTATION_TYPE }) 
@Retention(RUNTIME) 
@Documented 
@Constraint(validatedBy = ValidMapValidator.class) 
public @interface ValidMap { 
    String message() default "valid.map"; 

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

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

public class ValidMapValidator implements 
     ConstraintValidator<ValidMap, Map<?, ?>> { 

    @Override 
    public void initialize(final ValidMap annotation) { 
     return; 
    } 

    @Override 
    public boolean isValid(final Map<?, ?> map, 
     final ConstraintValidatorContext context) { 
     if (map == null || map.size() == 0) 
     return true; 

     // Iterate each map entry and validate 
     return true; 
    } 
} 
+0

はい、私はカスタムバリデーターを書き込もうとしましたが、タイプを知る必要がある実際のオブジェクトを評価しようとしました。 > constraintViolations = validator.validate(car)を設定します。 – liecno

+0

汎用タイプにはワイルドカードを使用できます。バリデータを設定する方法の例については、私の答えの編集を参照してください。 – Perception

関連する問題