前言
通过@Constraint注解实现自定义注解,指定对应的校验器,在校验方法中去引用枚举来调用特定校验逻辑,定义对应的枚举内校验接口,具体枚举实现其校验方法。
一、引入依赖
Springboot依赖可能自己引入了对应依赖,但是我在项目中自己引入了对应的validation依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
二、使用步骤
1.定义自定义注解
代码如下(示例):
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {GroupValidator.class})
@Documented
public @interface GroupValidate {
String message();
/**
* 用于校验的枚举
*/
Class<? extends Enum<?>> enumClass();
}
- Target:代表枚举可使用的地方,FIELD代表雷属性,METHOD代表方法,ANNOTATION_TYPE表示注解。
- Retention代表生命周期
- Constraint:内部指定对应校验器,为指定的参数去执行内部校验方法
- enumClass:通过定义该方法,我们可以在对应注解方法中去注入对应的枚举类
2.定义校验器
代码如下(示例):
public class GroupValidator implements ConstraintValidator<GroupValidate, Object> {
private Class<? extends Enum> enumClass;
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
GroupValidService[] enums = (GroupValidService[])enumClass.getEnumConstants();
if (ArrayUtil.isEmpty(enums)) {
return false;
}
return enums[0].existValidate(value);
}
@Override
public void initialize(GroupValidate constraintAnnotation) {
enumClass = constraintAnnotation.enumClass();
}
}
该处除了第二个泛型和isValid方法为固定格式,第二个泛型想用通配符但是没成功,只好用Object实现,内部校验方法会用枚举本身的校验方法去校验,从而让不同枚举可自定义校验逻辑
3.定义校验接口
public interface GroupValidService<T> {
/**
* 校验枚举值是否存在
* @param value 校验值
* @return 是否存在
*/
boolean existValidate(T value);
}
定义该接口, 每个枚举项实现具体校验逻辑
4. 枚举项
public enum UserTypeEnum implements GroupValidService<Integer> {
ADMIN(1),
USER(2);
private int type;
UserTypeEnum(int type) {
this.type = type;
}
@Override
public boolean existValidate(Integer value) {
return Arrays.stream(values()).anyMatch(typeEnum -> typeEnum.type == value);
}
}
5. 定义全局异常拦截器去拦截对应参数异常
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public BaseReturn methodValidationException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
String message = StrUtil.EMPTY;
if (bindingResult.hasErrors()) {
List<ObjectError> allErrors = bindingResult.getAllErrors();
message = allErrors.stream().map(ObjectError::getDefaultMessage)
.reduce(StrUtil::join).orElse(DEFAUT_ARGS_VALID_ERROR_MESSAGFE);
}
return new BaseReturn(404, message, null);
}
6. 具体使用
controller层通过@Validated注解开启校验
实现类中加入注解