使用注解对参数进行校验
为什么需要参数进行校验
在很多的时候,开发者预想的参数与用户期望的参数可能是不一致的。比如,程序期望用户输入电话号码,但是用户给了一段日期,在没有参数校验的时候,这个日期参数就代替原本的手机号码,使得程序收集到脏数据,对用户体验也很不好。这个时候,需要有参数校验使得输入的参数符合程序的预期,同时也给用户反馈,告知我们需要什么参数。
设计思路
使用切片注入的方式,在业务逻辑执行前,对参数进行校验。
具体如下
拦截所有请求
@Before("@annotation(org.springframework.web.bind.annotation.GetMapping)||" +
"@annotation(org.springframework.web.bind.annotation.PostMapping)||" +
"@annotation(org.springframework.web.bind.annotation.PutMapping)||" +
"@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
获取切入点的所有方法和注解
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
LOGGER.debug("Starting validate method {}.", method.getName());
Annotation[][] annotations = method.getParameterAnnotations();
Object[] parameters = point.getArgs();
对所有带Validated注解的入参进行校验
for (int i = 0; i < annotations.length; i++) {
for (int j = 0; j < annotations[i].length; j++) {
if (annotations[i][j] instanceof Validated) {
validateArg(parameters[i]);
}
}
}
对参数的所有变量进行校验
private void validateArg(Object arg) {
//获取所有的成员变量
Field[] fields = arg.getClass().getDeclaredFields();
for (Field field : fields) {
//获取所有实现Validator接口的bean,bean为具体注解的逻辑实现
Map<String, Validator> validatorMap = context.getBeansOfType(Validator.class);
for (Validator validator : validatorMap.values()) {
//如果成员变量有注解,将对成员变量进行参数校验
if (validator.support(field)) {
validator.handle(arg, field);
}
}
}
}