本示例是自定义的字典类型的注解,用以校验接口入参中的数据是否符合字典里面定义的值。
字典数据里面设置了字典编码和字典名称。
【1】注解@interface IsDictionary
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Document
@Constraint(
validateBy = IsDictionaryValidator.class
)
public @interface IsDictionary() {
// 自定义注解属性:type。字典类型,用以查询某类字典数据
String type() default "";
// 自定义注解属性:isCode。是否是校验字典编码
boolean isCode() default true;
// 自定义注解属性:isRequired。是否不能为空
boolean isRequired() default true;
// 一般都加以下三行
String message() default "参数不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@Target(ElementType.FIELD)
注解的作用目标,字段、枚举的常量
@Retention(RetentionPolicy.RUNTIME)
注解的保留位置,注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Document:说明该注解将被包含在javadoc中
@Constraint(validateBy = IsDictionaryValidator.class)
指定注解的处理逻辑类
【2】逻辑类 IsDictionaryValidator.java
public class IsDictionaryValidator implementes ConstraintValidator<IsDicitonary, Object> {
private boolean isRequired;
private boolean isCode;
private String type;
// 查询并校验字典数据的服务
private DictionaryManager dicitonaryManager;
@Override
public void initialize(IsDictionary constraintAnnotation) {
// 取注解中的值赋予到本类属性上面方便使用
isCode = constraintAnnotation.isCode();
isRequired = constraintAnnotation.isRequired();
type = constraintAnnotation.type();
}
/**
* 具体校验逻辑
*/
@Override
public void isValid(Object s, ConstraintValidatorContext constraintValidatorContext) {
if (null == s) {
return !isRequired;
}
if (isCode) {
return dictionaryManager.validateCode(s.toString(), type);
} else {
return dictionaryManager.validateName(s.toString(), type);
}
}
}
【3】使用方式
入参类 RecordReqDTO.java
@Data
public class RecordReqDTO() {
@IsDictionary(type = "color")
private Integer code;
@IsDictionary(type = "color", isCode = false, isRequired = false, message = "未知的颜色")
private String name;
}
接口
@PostMapping
public void test(@RequestBody @Validated RecordReqDTO req) {
...
}
@Validated 使校验型注解生效。