javaBean验证框架(4)—自定义约束
javaBean验证规范支持自定义注解进行扩展,上文中看到了一些内置的验证注解,实际应用中肯定不能完全我们,但可以很容易创建需要的验证注解,本文通过示例展示如何创建自定义约束。
创建注解
本文打算创建一个验证注解,被验证值必须是有效的语言名称。
新的注解必须指定@Constraint
注解,且其属性validateBy
需指定该验证注解的实现类,实现类类必须实现该注解。
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = LanguageValidator.class)
@Documented
public @interface Language {
String message () default "must be a valid language display name." +
" found: ${validatedValue}";
Class<?>[] groups () default {};
Class<? extends Payload>[] payload () default {};
}
下面看实现类;
创建验证器
实现类必须实现接口ConstraintValidator<A extends Annotation,T>
,实现代码定义验证逻辑,用于T类型中的属性/字段验证,我们需要验证‘Language’,使用@Language注解对字符串进行验证。
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Locale;
public class LanguageValidator implements ConstraintValidator<Language, String> {
@Override
public void initialize (Language constraintAnnotation) {
}
@Override
public boolean isValid (String value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.getDisplayLanguage().equalsIgnoreCase(value)) {
return true;
}
}
return false;
}
}
ConstraintValidatorContext是什么?
上面示例我们看到ConstraintValidatorContext
,其提供自定义约束的上下文数据和操作。
被验证的Bean
import com.dataz.validate.Language;
public class LanguageBean {
@Language
private String language;
public String getLanguage () {
return language;
}
public void setLanguage (String language) {
this.language = language;
}
}
验证
//验证自定义@Language注解
LanguageBean languageBean = new LanguageBean();
System.out.println(Locale.getDefault().getDisplayLanguage());
languageBean.setLanguage("China");
validator.validate(languageBean).stream().forEach(ValidationDemo1::printError);
验证结果为:
language must be a valid language display name. found: 中文