开发者

springbootAOP定义切点获取/修改请求参数方式

目录
  • AOP介绍
    • 1.六种通知方式
    • 2.ASPectJ相关注解
  • 定义切入点的两种方式
    • 1.注解
    • 2.表达式
  • 常用两种通知获取参数
    • 1.@Before
    • 2.@Around
  • 总结

    AOP介绍

    1.六种通知方式

    • 环绕通知:在目标方法执行前和执行后实施增强,可用于日志记录,事务处理等
    • 前置通知:在目标方法执行前实施增强,可用于权限管控等
    • 后置返回通知:在目标方法成功执行后实施增强,可用于关闭流,删除临时文件等
    • 后置通知:在目标方法执行后实施增强(无论方法是否发生异常都执行),可用于释放资源
    • 异常通知:在目标方法抛出异常时实施增强,可用于处理异常,记录日志等
    • 引入通知:在目标类中添加一些方法和属性,用于修改目标类

    2.AspectJ相关注解

    • @Aspect:用于定义一个切面,注解在切面类上
    • @Pointcut:用于定义切点表达式,在使用时,需要定义一个切入点方法,该方法返回值为void,且方法体为空的普通方法
    • @Before:用于定义前置通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式
    • @AfterReturning:用于定义后置返回通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式
    • @Around:用于定义环绕通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式
    • AfterThrowing:用于定义异常通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式。另外还有一个 throwing属性用于访问目标方法抛出的异常,该属性值与异常通知方法中同名的形参一致
    • After:用于定义后置最终通知,通常为其指定value属性,该值可以是已有切入点,编程客栈也可以定义切点表达式

    定义切入点的两种方式

    1.注解

    //定android义注解
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @inter编程客栈face SafetyHarness {
        String defaultValue() default "";
    }
    //切入点
    @Pointcut("@annotation(com.xx.xx.xx.web.annotation.SafetyHarness)")
        public void efficacyParameters(){
        }

    2.表达式

    //该controller所有方法,可以直接指定
    /*
    execution():表达式主体
    第一个 * 表示返回类型,使用*表示所有类型,该 * 与包名之间有一个空格
    第二个 * 表示类名
    第三个 * 表示方法名
    ..表示任意参数
    */
    @Pointcut("value = "execution(* com.xx.xx.xx.web.controller.*.* (..)))")
        public void efficacyParameters(){
        }

    常用两种通知获取参数

    1.@Before

    @Before("efficacyParameters()")
        public void beforeEfficacyParameters(JoinPoint joinPoint){
                //获取请求参数
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
                Map<String, String[]> parameterMap = request.getParameterjsMap();
            	//通过参数名获取
                Object ext1 = parameterMap.get("ext1");
                Object ext2 = parameterMap.get("ext2");
        }

    2.@Around

    	@Around("efficacyParameters()")
        public T beforeEfficacyParameters(ProceedingJoinPoint joinPoint){
            	//接口返回结果,该结果可在业务前或业务后执行
                Object proceed = joinPoint.proceed();
       			
                Object[] obj = joinPoint.getArgs();
                phpif (obj == null || obj.length == 0) {
                    return T;
                }
               //获取请求参数 
                Map<String, Object> fieldsName = getFieldsName(joinPoint);
                Object ext1 = fieldsName.get("ext1");
                //POST请求强转
                SafetyAuditPageVo ext2 = (SafetyAuditPageVo) fieldsName.get("ext");
    
    			//修改请求参数
    			SafetyAuditPageVo vo = (SafetyAuditPageVo) obj[0];
                    vo.setXxxx("XXXXXX");
                    obj[0] = vo;
                    return  joinPoint.proceed(obj);
        }
    
    	private static Map<String, Object> getFieldsName(ProceedingJoinPoint joinPoint) {
          
            Object[] args = joinPoint.getArgs();
            ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            String[] parameterNames = pnd.getParameterNames(method);
            Map<String, Object> paramMap = new HashMap<>(32);
            for (int i = 0; i < parameterNames.length; i++) {
                paramMap.put(parameterNames[i], args[i]);
            }
            return paramMap;
        }

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜