spring参数统一校验 | 张扎瓦的博客

spring参数统一校验

使用spring aop 实现特定接口参数统一校验


问题场景

  写过接口的人都会面临一个问题,那就是参数校验的问题。尽管客户端有参数校验,但经验告诉我们,仅仅依赖客户端是极大的错误。通常情况下,我们都应该认为,客户端传过来的参数都是不可信任的。每个参数都应该经过合理的校验才能使用,否则迟早会发生不可预料的问题。

  基于上述的问题,最简单的解决办法就是在每个接口上,都加上参数校验。关键的地方来了,怎么加?接口少了还好说,修改代码就行,接口多了呢?几百个几千个,怎么办?

使用AOP解决问题

  AOP(Aspect Oriented Programming ),中文叫面向切面编程。程序运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程 。其实本质上是一种动态代理技术。

  有了AOP,我们就可以写一个通用的参数校验方法,对所有需要参数校验的接口进行统一处理了。而且对原来的代码没有侵入性,符合开闭原则。

下面是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Component
@Aspect
public class CheckParametersEmpty {

/**
* 检查com.zbrx.speed.controller包下所有的返回值为ResultData的方法,
* 如果参数有空,则阻止执行,并直接返回结果
* 否则继续执行
* @throws Throwable
*
*/
@Around("execution(com.zbrx.speed.base.dto.ResultData com.zbrx.speed.controller..*.*(..))")
public Object checkParam(ProceedingJoinPoint point) throws Throwable {
//获取方法的请求参数
Object[] params = point.getArgs();

//获取方法
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature)signature;
Method targetMethod = methodSignature.getMethod();

//检测方法上是否有 @IgnoreParams注解,如果有,则不检测参数,直接向下执行
IgnoreParams ignoreParams = targetMethod.getAnnotation(IgnoreParams.class);
if (ignoreParams != null) { //如果有注解
return point.proceed(params); //直接执行向下执行
}

//遍历参数,查看是否有空值
for (Object object : params) {
if (object == null) { //如果参数有空值,直接返回
return ResultData.error(ResponseCode.PARAM_EMPTY);
}
}

//否则继续往下执行
return point.proceed(params);
}
}

@Around指定了切入点,也就是哪些方法需要进行参数校验。关于SpringAOP具体的介绍,我会在另一篇博客中说明。

如果我的文章对您有所帮助,不妨打赏一杯豆浆以资鼓励(○` 3′○)