1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > SpringBoot - 利用Spring Aop和自定义注解@CheckParam实现方法参数的校验

SpringBoot - 利用Spring Aop和自定义注解@CheckParam实现方法参数的校验

时间:2019-02-14 22:09:31

相关推荐

SpringBoot - 利用Spring Aop和自定义注解@CheckParam实现方法参数的校验

文章目录

1. Spring AOP 概念2. 自定义注解 @CheckParam3. 定义Spring AOP切面 CheckParamAspect4. 使用自定义注解
1. Spring AOP 概念

Advice(通知、切面): 某个连接点所采用的处理逻辑,也就是向连接点注入的代码, AOP在特定的切入点上执行的增强处理。

@Before: 标识一个前置增强方法,相当于BeforeAdvice的功能.@After: 不管是抛出异常或者正常退出都会执行.@AfterReturning: 后置增强,似于AfterReturningAdvice, 方法正常退出时执行.@AfterThrowing: 异常抛出增强,相当于ThrowsAdvice.@Around: 环绕增强,相当于MethodInterceptor.

JointPoint (连接点):程序运行中的某个阶段点,比如方法的调用、异常的抛出等。

Pointcut (切入点): JoinPoint的集合,是程序中需要注入Advice的位置的集合,指明Advice要在什么样的条件下才能被触发,在程序中主要体现为书写切入点表达式。

@Aspec t(切面): 通常是一个类的注解,里面可以定义切入点和通知;

2. 自定义注解 @CheckParam

package com.hh.annotation;/*** 校验方法入参合法性*/@Target({ElementType.PARAMETER, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)public @interface CheckParam {/*** 是否可以为空*/boolean required() default true;/*** 需要校验的参数长度*/int length() default 0;/*** 是否为白名单模式*/boolean isWhiteMode() default true;/*** 是否校验字符串合法*/boolean isCheckLegal() default true;}

3. 定义Spring AOP切面 CheckParamAspect

@Slf4j@Aspect@Component@EnableAspectJAutoProxypublic class CheckParamAspect {/*** 字符校验黑白名单*/private static final String WHITE_CHARACTER = "qwertyuiopasdfghjklzxcvbnm0123456789_";private static final String BLACK_CHARACTER = "!@#¥%";// 用于匹配当前执行方法持有指定注解的方法;@Pointcut("@annotation(com.hh.annotation.CheckParam)")private void checkParamCut() {}@Around("checkParamCut()")public Object checkCharacterLegalAdvice(ProceedingJoinPoint joinPoint) throws Throwable {Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;// 获取方法的参数Parameter[] params = methodSignature.getMethod().getParameters();// 获取方法的参数名称String[] paraNames = methodSignature.getParameterNames();// 获取方法的参数值Object[] args = joinPoint.getArgs();for (int i = 0; i < params.length; i++) {// 获取方法的每个参数上指定类型的注解CheckParam annotation = params[i].getAnnotation(CheckParam.class);// 字段长度检验if (Objects.nonNull(annotation)) {// 非空校验:required=true,但是属性值却为空if (annotation.required() && StringUtils.isEmpty(args[i])) {log.error("Parameter is required, message: parameter= {} value= {}", paraNames[i], args[i]);throw new RuntimeException("storage.parameter.not.null");}// 字符长度校验if (String.valueOf(args[i]).length() > annotation.length()) {log.error("Parameter is too long, message: parameter= {} value= {} maxLength = {}", paraNames[i], args[i], annotation.length());throw new RuntimeException("storage.parameter.too.long");}// 黑白名单检验if (annotation.isCheckLegal() && checkStringIllegal(String.valueOf(args[i]), annotation.isWhiteMode())) {log.error("Parameter is illegal, message: parameter= {} value= {}", paraNames[i], args[i]);throw new RuntimeException("storage.parameter.illegal");}}}return joinPoint.proceed();}/*** 匹配是否含有特殊字符*/public boolean checkStringIllegal(String content, boolean isWhiteMode) {char[] allowCharArray = isWhiteMode ? WHITE_CHARACTER.toCharArray() : BLACK_CHARACTER.toCharArray();// 匹配是否为常用字符boolean flag = false;// 不能去掉Arrays.sort(allowCharArray);// 将字符串转为字符数组char[] contentCharArray = content.toLowerCase().toCharArray();// 遍历字符数组,判断每个字符是否在白名单中for (int i = 0; i < contentCharArray.length; i++) {// 二分查找if (Arrays.binarySearch(allowCharArray, contentCharArray[i]) <= -1) {flag = true;break;}}return flag;}}

4. 使用自定义注解

@RestControllerpublic class UserController {@Autowiredprivate UserService userService;@PostMapping("/add")public ApiResponse<T> add(@RequestBody UserEntity userEntity){userService.insertUser(userEntity.getId(),userEntity.getName(),userEntity.getPassword(),userEntity.getCreateTime());return new ApiResponse<T>(0,"success");}}

@Servicepublic class UserService {@CheckParampublic void insertUser(Integer id,@CheckParam(length = 48) String name,@CheckParam(length = 10000, isCheckLegal = false, required = false) String password,Date createTime){System.out.println(id);}}

debug下的各个Spring AOP 切面中的参数:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。