私は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].value
とstrings[2]
(であること方法などであるjavax.validation.Path
オーバーライドの実装を休止サンプル上記のeコード)。
質問:私のナビゲーションアプローチは間違っていますか?ConstraintViolation
からそのようなマッピングを抽出する別の方法がありますか?それともこれは(私がTYPE_USE
注釈の前に、彼らが実装さgetIndex
アプローチは、それはちょうど私が(私はこの問題との最初のGoogleしようとしましたが、できなかったのです奇妙な感じ?
全く大丈夫だったことがわかります休止開発者向けの機能要求であります最も近いもの:https://github.com/hibernate/hibernate-validator/pull/441)私は間違いが冬眠の制限ではなく私のものかどうか疑問に思っています
フィードバックをいただきありがとうございます。ここの問題:https://hibernate.atlassian.net/browse/HV-1121。私は自分自身でPRを開くことも考えているかもしれません(ただし、確実に日曜日の前にはありません) – ThanksForAllTheFish
この問題は、Hibernate Validator 5.3.0.Finalで修正されています。 –