![](/img/trans.png)
[英]Is it possible to check at runtime whether or not a TYPE_USE annotation is present on an interface within a implements declaration?
[英]TYPE_USE annotation in hibernate validator
我知道 hibernate 驗證器支持TYPE_USE
注釋:雖然它沒有定義自己的注釋,但它允許您定義和使用自定義注釋。
我可以正確定義和驗證這樣的注釋(很快代碼),但是我想將錯誤映射到用於向用戶顯示錯誤的路徑中。
給出以下示例
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-- ),這對於第一種情況,但第二種情況失敗(我找不到檢索失敗對象索引的方法)。 我認為原因在於 hibernate-validator 中javax.validation.Path.PropertyNode的實現(我目前在5.2.4.Final
版本5.2.4.Final
,代碼看起來與鏈接的5.2.1.Final
的相同。供參考:
@Override
public final Integer getIndex() {
if ( parent == null ) {
return null;
}
else {
return parent.index;
}
}
使用TYPE_USE
這種方法在我看來是行不通的,因為失敗的對象是葉子,因此沒有子節點可以從中檢索索引。
很不錯, javax.validation.Path
休眠實現覆蓋了toString
方法,這樣的方法javax.validation.Path
violation.getPropertyPath().toString()
是beans[1].value
和strings[2]
(在上面的示例代碼中)。
所以,對於問題:我的導航方法是錯誤的,還有另一種方法可以從ConstraintViolation
提取這樣的映射嗎? 或者這是對休眠開發人員的功能請求(我可以看到在TYPE_USE
注釋getIndex
他們實現的getIndex
方法完全沒問題?
只是感覺很奇怪我是第一個遇到這個問題的人(我試圖用谷歌搜索並找不到任何相關的東西,最接近的是: https : //github.com/hibernate/hibernate-validator/pull/441 )所以我想知道錯誤是否是我的而不是休眠限制
我同意應該為該值設置索引,並認為您在 Hibernate Validator 中發現了一個問題。 你能在我們的JIRA 跟蹤器中打開一個問題嗎?
順便提一句。 TYPE_USE 級別約束的概念將從 Bean Validation 2.0 開始標准化。 所以這個領域可能會有更多的變化,特別是我想知道那個節點應該有什么Kind
(目前它是PROPERTY
似乎有問題)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.