javaBean验证框架(4)—自定义约束

时间:2022-09-29 19:09:00

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: 中文