2016-10-05 10 views
1

私はhibernateバリデーターがTYPE_USEアノテーションをサポートしていることを知っています:それは独自のものを定義していませんが、カスタムのものを定義して使用することができます。TYPE_USEアノテーションはhibernateバリデーターで

私はそのようなアノテーションを正確に定義して検証することができますが、エラーをユーザーに表示するために使用されるパスにマップしたいと考えています。考えると、サンプル、次の

public class SampleTest { 

    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); 

    public static class LimitedSizeStringValidator implements ConstraintValidator<LimitedSize, String> { 

     private LimitedSize constraint; 

     @Override 
     public void initialize(LimitedSize constraintAnnotation) { 
      this.constraint = constraintAnnotation; 
     } 

     @Override 
     public boolean isValid(String value, ConstraintValidatorContext context) { 
      String s = Ensure.notNull(value); 
      return s.length() >= constraint.min() && 
       s.length() <= constraint.max(); 
     } 
    } 

    @Retention(RUNTIME) 
    @Documented 
    @Target({TYPE_USE}) 
    @Constraint(validatedBy = {LimitedSizeStringValidator.class}) 
    public @interface LimitedSize { 

     String message() default "{javax.validation.constraints.Size.message}"; 

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

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

     int min() default 0; 

     int max() default Integer.MAX_VALUE; 
    } 

    private static class TestBean { 
     @Valid 
     private Collection<@LimitedSize(max = 3) String> strings = new ArrayList<>(); 

     @Valid 
     private Collection<InnerBean> beans = new ArrayList<>(); 
    } 

    private static class InnerBean { 
     @Min(3) 
     private final int value; 

     private InnerBean(int value) { 
      this.value = value; 
     } 
    } 

    @Test 
    public void testBeanInvalid() { 

     TestBean testBean = new TestBean(); 

     assertThat(validator.validate(testBean)).isEmpty(); 

     testBean.strings.add("ok"); 
     testBean.strings.add("ok2"); 
     testBean.beans.add(new InnerBean(4)); 
     assertThat(validator.validate(testBean)).isEmpty(); 

     testBean.strings.add("not_ok"); 
     testBean.beans.add(new InnerBean(2)); 

     Set<ConstraintViolation<TestBean>> violations = validator.validate(testBean); 
     assertThat(violations).hasSize(2); 

     StreamSupport.stream(violations.spliterator(), false) 
      .forEach(v -> { 
       System.out.println(v.getPropertyPath()); 
       System.out.println(v.getMessage()); 
       v.getPropertyPath().forEach(p -> System.out.print("'" + p.getName() + (p.getIndex() != null ? "[" + p.getIndex() + "]" : "") + "' -> ")); 
       System.out.println(); 
      }); 
    } 
} 

私は

errors: [ 
    ["beans", "1", "value"], 
    ["strings", "2"] 
] 

私のサンプルのように、現時点での私のアプローチは、違反パスをナビゲートしているように、オブジェクトのエラーをマップしたいと思います(http://docs.oracle.com/javaee/7/api/javax/validation/ConstraintViolation.html#getPropertyPath-- )は、最初のケースでは完全に動作しますが、2番目のケースでは失敗します(失敗したオブジェクトのインデックスを取得する方法が見つかりません)。私は、バージョン5.2.4.Final上で、現在午前(理由は休止状態、バリでjavax.validation.Path.PropertyNodeの実装であると思うし、コードがリンクされ5.2.1.Finalと同じに見えます参考のために:。

@Override 
public final Integer getIndex() { 
    if (parent == null) { 
     return null; 
    } 
    else { 
     return parent.index; 
    } 
} 

TYPE_USEでは、このアプローチは動作しないことができます私の意見では、失敗したオブジェクトが葉であるので、これは子ノードは、それから、インデックスを取得することはできません。十分な

ニース、toString方法はviolation.getPropertyPath().toString()beans[1].valuestrings[2](であること方法などであるjavax.validation.Pathオーバーライドの実装を休止サンプル上記のeコード)。

質問:私のナビゲーションアプローチは間違っていますか?ConstraintViolationからそのようなマッピングを抽出する別の方法がありますか?それともこれは(私がTYPE_USE注釈の前に、彼らが実装さgetIndexアプローチは、それはちょうど私が(私はこの問題との最初のGoogleしようとしましたが、できなかったのです奇妙な感じ?

全く大丈夫だったことがわかります休止開発者向けの機能要求であります最も近いもの:https://github.com/hibernate/hibernate-validator/pull/441)私は間違いが冬眠の制限ではなく私のものかどうか疑問に思っています

答えて

1

私はインデックスをその値に設定して、Hibernate Validatorで問題を発見したと思っています。 JIRA trackerで問題を開きますか?

Btw。 TYPE_USEのレベル制約は、Bean Validation 2.0時点で標準化されます。ですから、このエリアにはさらにいくつかの変更があります。具体的には、Kindにはノードがあるはずです(現在はPROPERTYと思われます)。

+0

フィードバックをいただきありがとうございます。ここの問題:https://hibernate.atlassian.net/browse/HV-1121。私は自分自身でPRを開くことも考えているかもしれません(ただし、確実に日曜日の前にはありません) – ThanksForAllTheFish

+0

この問題は、Hibernate Validator 5.3.0.Finalで修正されています。 –

関連する問題