我正在使用validation-api-2.0.1.Final
和hibernate-validator-6.0.13.Final
。我想对以下情况进行验证,
我已经创建了一个自定义验证来验证List<Map<String,Object>>
BookInfo.java
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {BookInfoValidator.class}
)
public @interface BookInfo {
String message() default "Should not be empty";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
BookInfoValidator.java
public class BookInfoValidator implements ConstraintValidator<ValidateUserInfo, List<Map<String, Object>>> {
private final ContentRepositoryClient contentRepository;
public ValidateUserInfoValidator(ContentRepositoryClient contentRepository) {
this.contentRepository = contentRepository;
}
@Override
public void initialize(ValidateUserInfo constraintAnnotation) {
}
@Override
public boolean isValid(List<Map<String,Object>> map, ConstraintValidatorContext constraintValidatorContext) {
//In the list of Map the key will be "text,email,date etc etc" based on the key i would like to
//validate with the proper validation constraints
//ex) for Email invoke javax.validation.constraints.Email.class from validation-api
//I am not sure how to manually invoke the validation annotations.
return false;
}
}
BookInfoView.java
class BookInfoView {
@BookInfo
private List<Map<String, Object>> bookInfos;
}
在“地图”列表中,键为“文本,电子邮件,日期等”。基于密钥,我想使用适当的验证约束进行验证
电子邮件从验证API调用javax.validation.constraints.Email.class
的异常。我不确定如何手动调用验证批注。
任何提示或帮助将不胜感激。
答案 0 :(得分:4)
我不确定如何手动调用验证注释。
我正在回答以上引用的行。 是,可以以编程方式调用验证,如果验证失败,您将收到一组中的所有失败消息。以下是执行相同操作的步骤:
ValidatorFactory
Validator
获取ValidatorFactory
实例validate()
方法进行验证constraintViolations.iterator().next().getMessage()
显示一些代码,下面是上述所有四个步骤的代码段:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<BookInfoView>> constraintViolations = validator.validate(bookInfoViewObj);
assertEquals( "Should not be empty", constraintViolations.iterator().next().getMessage() );
Hibernate Validator框架提供了各种其他功能来验证一个或多个实体,然后处理结果。最好您看看official document。
答案 1 :(得分:0)
访问约束的验证器实现没有“不错”的方式(电子邮件,非null等)。虽然您可以创建这些验证器的实例并将其存储在BookInfoValidator
中,但是您需要做很多其他工作。对于每个验证器,其ConstraintValidator#initialize()
方法。尽管在诸如@NotNull
这样的简单约束的情况下,实际上要注意进行初始化,但是如果没有该验证器,则可以轻松地执行相同的检查。而且,对于像@Email
这样的更复杂的类,您需要为注释创建自己的代理类,以便正确初始化约束验证器。
话虽如此,我建议为您的Map
写一个包装类,例如:
public class BookInfoWrapper {
private final Map<String, Object> data;
public BookInfoWrapper(Map<String, Object> data) {
this.data = data;
}
@NotNull
public Map<String, Object> getUser(){
return (Map<String, Object>) data.get( "user" );
}
@Email
public String getEmail(){
return Objects.toString(( getUser() ).get( "email" ));
}
// and any other constraints you need
}
然后在验证之前将地图列表转换为这些包装器。
我还可以看到您的验证器中有一个存储库,因此我认为您可能希望“动态”导出规则。在这种情况下,您可能想查看Hibernate Validator提供的programmatic API。使用它,您应该能够根据从数据库中检索到的数据来构建所需的规则。但是,仍然需要先包装地图。
总结一下,遗憾的是,还没有针对您的特定情况的简便解决方案。我们正在对自由格式对象进行验证,但是要花一些时间才能发布它。因此,我建议您要么
BookInfoValidator
中自己编写验证检查,而无需使用内置约束。