Hibernate Validator 6.0.7.Final 之一(宣告Bean約束之容器元素的約束)
阿新 • • 發佈:2018-11-24
首先,我們需要知道什麼是容器元素–其實就是List、Set、Map等。我們也知道,使用容器元素的時候,需要指定容器能容納的資料的型別,例如,List<String>
就是說這個List容器可以容納String型別,這裡的String叫做引數化型別。本文要講的就是對引數化型別約束。
需要注意的是,如果想要將一個約束應用到引數化型別上,那麼這個約束的定義中的@Target中必須包含ElementType.TYPE_USE。什麼意思呢?我們以validator-api標準的非空約束為例解釋一下。從該約束的定義中我們可以看到它的@Target中包含了TYPE_USE這個值,由此,我們知道@NotNull約束可以被應用到引數化型別上。
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {
String message() default "{javax.validation.constraints.NotNull.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
/**
* Defines several {@link NotNull} annotations on the same element.
*
* @see javax.validation.constraints.NotNull
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention (RUNTIME)
@Documented
@interface List {
NotNull[] value();
}
}
截止Bean Validation 2.0,Bean Validation(JSR標準)內建的和Hibernate Validator(JSR標準的實現)特有的約束都指定了ElementType.TYPE_USE。所以,我們可以直接在引數化型別上使用這些約束。但是,如果想要在引數化型別上使用自定義的約束,一定記得將ElementType.TYPE_USE加到自定義的約束上。
內建的受支援的容器元素有這些:java.util.Iterable的實現(List、Set等)、java.util.Map的實現、java.util.Optional、java.util.OptionalInt、java.util.OptionalDouble、java.util.OptionalLong等。自定義的容器元素的約束本文不講。
下面,我們以Set為例子來感性認識一下容器約束。
public class Car {
private Set<@NotNull String> parts = new HashSet<>();
public Set<String> getParts() {
return parts;
}
public void setParts(Set<String> parts) {
this.parts = parts;
}
}
@Test
public void setTest() {
Car car = new Car();
Set<String> parts = new HashSet<>();
parts.add("wheel");// 沒問題
parts.add("");// 沒問題
parts.add(null);// 有問題
car.setParts(parts);
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);
logger.info("違反的約束的個數:{}", constraintViolations.size());
for (ConstraintViolation<Car> constraintViolation : constraintViolations) {
logger.info("違反的約束:{}, {}", constraintViolation.getExecutableReturnValue(),
constraintViolation.getMessage());
}
}
INFO [main] com.qs.mmeng.hibernate.validator.constraints.container.ContainerElementConstraintTest.setTest : 違反的約束的個數:1
INFO [main] com.qs.mmeng.hibernate.validator.constraints.container.ContainerElementConstraintTest.setTest : 違反的約束:null, 不能為null
當然,這個例子非常簡單,其他的容器元素也都是類似的。