提要
本文是 小小商城-SSM 版的 细节详解系列 之一,项目 github:https://github.com/xenv/S-mall-ssm 本文代码大部分在 github 中 可以找到。
参数校验就是对用户 GET 或者 POST 传进来的参数进行校验是否合法。最简单的方法就是在每个控制器方法中,一个一个用 if 校验,但是这样效率很低。
那么,还有没有别的方法呢?SpringMVC 官方推荐是使用 hibernate-validate 校验框架,但是使用起来可以说是很麻烦了,还要针对 每个 实体,再写校验器,工作量巨大。
在此,我用 自定义 AOP 切面 的方法,结合 自定义参数注解,非常方便的就实现了简单的参数校验(这里以非空校验为例),实现的效果如下:
1 2 3
| @RequestMapping("search") public String search(String keyword, @Nullable String sort, Model model) throws Exception { }
|
对于 sort 参数,访问的时候可能并不一定会传进来,我们使用 @Nullable 进行标记(这个是我们定义的注解),否则将默认进行 非 null 检测,这样就可以大大减少空指针错误发生的几率。
有些朋友可能会问,为什么不使用 SpringMVC 的拦截器,而是要用 AOP 的方法呢,这里我画个图给大家解释一下:
如果是用拦截器,拦截器会在函数调用前就拦截,这样我们就没有办法做数据校验了,而 AOP 切点则在函数调用后,函数体调用前可以拦截,那么我们用 AOP 做校验就非常合适。
具体实现
1.定义参数注解 (这里我只弄了个 Nullable 可空,其他不加这个默认非空)
1 2 3 4 5
| @Retention(RetentionPolicy.RUNTIME) @Target({PARAMETER}) public @interface Nullable {
}
|
2. 配置 AOP
具体的不展开讲了,网上很多,Maven 两个依赖,Spring 和 SpringMVC 都要加配置,还要加 XML 的域,就基本配置好了
3. 编写 AOP 切面
VerificationAspect.java
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 39 40
| @Aspect @Component public class VerificationAspect {
@Pointcut("execution(public * tmall.controller.*.*Controller.*(..))") public void joinPointInAllController() { }
@Before("joinPointInAllController()") public void checkParameter(JoinPoint point) throws ParameterException { Object[] args = point.getArgs(); Method method = ((MethodSignature) point.getSignature()).getMethod(); Parameter[] parameters = method.getParameters(); ArrayList<Object> argsWithoutNullable = new ArrayList<>(); for (int i = 0; i < parameters.length; i++) { Parameter parameter = parameters[i]; Annotation[] annotations = parameter.getDeclaredAnnotationsByType(Nullable.class); if (annotations.length < 1) { argsWithoutNullable.add(args[i]); } } for (Object o : argsWithoutNullable) { if (o == null) { throw new ParameterException("非法请求,参数不全"); } } } }
|
OK,其实非常简单了。