🍀SpringBoot:RequestParam方式参数校验实现
一、创建参数校验注解
@Documented
@Constraint(validatedBy = FieldValidatorHandler.class)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldValidator {
String message() default "Invalid value";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 数值或字符串的最小长度/值
*
* @return 字符串最小长度,数字最小值
*/
int min() default Integer.MIN_VALUE;
/**
* 数值或字符串的最大长度/值
*
* @return 字符串最大长度,数字最大值
*/
int max() default Integer.MAX_VALUE;
/**
* 字段是否可以为空
*
* @return true or false
*/
boolean notNull() default false;
}
二、通用字段校验器实现
实现ConstraintValidator接口
public class FieldValidatorHandler implements ConstraintValidator<FieldValidator, Object> {
private int min;
private int max;
private boolean notNull;
// 存储类型与校验逻辑的映射
private static final Map<Class<?>, FieldValidatorFunction<?>> VALIDATOR_MAP = new HashMap<>();
static {
// 注册字符串类型的校验器
VALIDATOR_MAP.put(String.class, (value, min, max) -> {
int length = ((String) value).length();
return length >= min && length <= max;
});
// 注册 Integer 类型的校验器
VALIDATOR_MAP.put(Integer.class, (value, min, max) -> {
int intValue = (Integer) value;
return intValue >= min && intValue <= max;
});
// 注册 Long 类型的校验器
VALIDATOR_MAP.put(Long.class, (value, min, max) -> {
long longValue = (Long) value;
return longValue >= min && longValue <= max;
});
// 注册 Double 类型的校验器
VALIDATOR_MAP.put(Double.class, (value, min, max) -> {
double doubleValue = (Double) value;
return doubleValue >= min && doubleValue <= max;
});
// 注册 Float 类型的校验器
VALIDATOR_MAP.put(Float.class, (value, min, max) -> {
float floatValue = (Float) value;
return floatValue >= min && floatValue <= max;
});
}
@Override
public void initialize(FieldValidator fieldValidator) {
this.min = fieldValidator.min();
this.max = fieldValidator.max();
this.notNull = fieldValidator.notNull();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
// 如果值为 null,检查是否允许为空
if (value == null) {
return !notNull;
}
// 获取值的类型
Class<?> valueType = value.getClass();
// 根据类型查找对应的校验器并校验
@SuppressWarnings("unchecked") // 注册时确保了泛型类型正确, 这里强转是安全的
FieldValidatorFunction<Object> validator = (FieldValidatorFunction<Object>) VALIDATOR_MAP.get(valueType);
if (validator != null) {
return validator.validate(value, min, max);
}
// 如果是没有注册的类型,则直接放行
return true;
}
字段有效性校验函数式接口
@FunctionalInterface
public interface FieldValidatorFunction<T> {
/**
* 校验字段值是否有效
*
* @param value 字段值
* @param min 最小值
* @param max 最大值
* @return true or false
*/
boolean validate(T value, int min, int max);
}
License:
CC BY 4.0