SpringBoot 通过ASpectJ 自定义注解进行参数非空验证

以下:内容主要参考https://blog.csdn.net/piaoranyuji/article/details/89448632。部分内容有参考已标注,如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正。

整体是: 在ParamsCheckASpect中对整个controller目录下的所有controller类的所有方法进行监听,如果方法中的参数有ParamCheck注解,且其notNull为true时会进行非空校验,如果是空则抛出异常,由全局异常类捕获。
不过思想有点跑偏了,这个写法感觉已经偏离了Aop的思想了。如果我要过滤全部的Controller的全部方法,用拦截器会更合适吧。不过也是算熟悉一下AOP方面

1. pom.xml中引入ASpectJ 依赖


		<!--引入AOP相应的注解-->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.5</version>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.8.9</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>3.2.2</version>
		</dependency>

2. 自定义参数验证注解

@Retention(RetentionPolicy.RUNTIME)			//生命周期在运行期
@Target({ElementType.METHODPARAMETER)			// 在参数上使用
@Documented			// 保存在JavaDoc中
public @interface ParamCheck {
    boolean notNull() default true;
}

3. 开启AspectJ 自动代理(在启动类上加)

@SpringBootApplication
@EnableTransactionManagement
@EnableAspectJAutoProxy (proxyTargetClass = true)    // 启用AspectJ 自动代理
public class UtilplatformApplication {

	public static void main(String[] args) {
		SpringApplication.run(UtilplatformApplication.class, args);
	}

}

4. 自定义异常类

public class ParamsException extends Exception {
    private String paramName;
    private String paramType;

    public ParamsException() {
        super("必填参数为空");
    }

    public ParamsException(String paramName, String paramType) {
        this.paramName = paramName;
        this.paramType = paramType;
    }

    public ParamsException(String message) {
        super(message);
    }

    public ParamsException(String message, Throwable cause) {
        super(message, cause);
    }

    public ParamsException(Throwable cause) {
        super(cause);
    }

    public ParamsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    @Override
    public String getMessage() {
        return paramName + "  " + paramType + "  参数不能为null";
    }
}

5. 定义全局异常捕获类

@ControllerAdvice   // controller 的通知
// 可以写多个ExceptionHandler注解的不同异常的类
public class GlobalExceptionHandler {
    /**
     *  参数异常
     * @param e
     * @return
     */
    @ExceptionHandler(ParamsException.class)
    @ResponseBody
    public JsonResult<Object> paramsExcetion(ParamsException e) {
        JsonResult<Object> objectJsonResult = new JsonResult<>();
        objectJsonResult.setFailSystemError(e.getMessage());
        return objectJsonResult;
    }
//
//    /**
//     *  总异常
//     * @param e
//     * @return
//     */
//    @ExceptionHandler(Exception.class)
//    @ResponseBody
//    public JsonResult<Object> excetion(Exception e) {
//        JsonResult<Object> objectJsonResult = new JsonResult<>();
//        objectJsonResult.setFailSystemError(e.getMessage());
//        return objectJsonResult;
//    }




}

6. 定义拦截器

@Component
@Aspect     
public class ParamsCheckASpect {
    @Pointcut("execution(public * com.kingfish.controller.*.*(..))")
//    @Pointcut("@annotation(com.kingfish.commons.aspect.ParamCheck)")    // 切点为注解,只能切方法上的注解
    public void checkParams() {

    }
    // 执行过程是 around - before - 逻辑代码 - after - afterReturning - (如果出现异常)afterThrowing
    @Around("checkParams()")
//    @Around("execution(public * com.kingfish.controller.*.*(..))")  // 也可以通过这种方式执行情况
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取切点的署名
        Method method = signature.getMethod();  // 得到拦截的方法
        //获取方法参数注解,返回二维数组是因为某些参数可能存在多个注解  --- 如果该方法参数都没有注解则直接跳过
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        if (parameterAnnotations == null || parameterAnnotations.length == 0) {
            return joinPoint.proceed();
        }
        // 获取参数名
        String[] parameterNames = signature.getParameterNames();
        Object[] args = joinPoint.getArgs();    // 获取参数值
        //获取方法参数类型
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (int i = 0; i < parameterAnnotations.length; i++) {
            for (int j = 0; i < parameterAnnotations[0].length; j++) {
                // 如果参数注解不为空,且参数注解是ParamCheck的派生类,且notNull是true,且 参数值为null 抛出空异常
                if (parameterAnnotations[i][j] != null && parameterAnnotations[i][j] instanceof ParamCheck
                        && ((ParamCheck) parameterAnnotations[i][j]).notNull() && args[i] == null) {
                    throw new ParamsException(parameterNames[i], parameterTypes[i].getTypeName());
                }
            }
        }

        return joinPoint.proceed();
    }

    @Before("checkParams()")
    public void before(){
        System.out.println("执行了before");
    }
}

7. Controller 调用

    @RequestMapping("/getToolsList")
    // 这里notNull设置成false,即不会查空
    public JsonResult<List<PlatTools>> getToolsList( @ParamCheck(notNull = false) String category, @ParamCheck String account, String keyword) {
        JsonResult<List<PlatTools>> jsonResult = new JsonResult<>();
        try {
            List<PlatTools> toolsList = platToolsService.getToolsList(category, account, keyword);
            jsonResult.setSuccess(toolsList);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setFailSystemError(e.getMessage());
        }
        return jsonResult;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫吻鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值