controller层获取aop方法返回的值

问题描述:
做的内容大致是阻止用户恶意不断请求,限制单位时间内访问次数
然后做了一个aop,但是我没法在controller层中获取aop方法的返回值,如下代码:

 @Pointcut("execution(public * com.mzd.redis_springboot_mybatis_mysql.controller.*.*(..))")
    public void WebPointCut() {
    }

    @Before("WebPointCut() && @annotation(times)")
    public boolean ifovertimes(final JoinPoint joinPoint, RequestTimes times)  {
        try {
            Object[] objects = joinPoint.getArgs();
            HttpServletRequest request = null;
            for (int i = 0; i < objects.length; i++) {
                if (objects[i] instanceof HttpServletRequest) {
                    request = (HttpServletRequest) objects[i];
                    break;
                }
            }
            if (request == null) {
                return true;
            }
            String ip = request.getRemoteAddr();
            String url = request.getRequestURL().toString();
            String key = "ifovertimes".concat(url).concat(ip);
            long count = redisTemplate.opsForValue().increment(key, 1);
            //如果是第一次,则设置过期时间
            if (count == 1) {
                redisTemplate.expire(key, times.time(), TimeUnit.MILLISECONDS);
            }
            if (count <= times.count()) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

然后我要controller层中怎么获取这个boolean值,到底是到访问次数上限了还是未到访问次数上限

阅读 7.3k
5 个回答

这个场景应该使用@Around环绕注入,当判断超过限制次数时直接返回异常信息,不再执行Controller方法;
另外Controller依赖aop的返回值也是可以做到,但不是良好的程序设计,这样违背了AOP的初衷

了解一下有没有什么API可以获取,如果没有,把boolean值放到request域对象中,在Controller方法里面是可以取到的。

Here is the code~

@Around("...")
public Object controllerLogAround(ProceedingJoinPoint pjp) throws Throwable {
    ...
    // 方法形参
    Object[] methodArgs = pjp.getArgs();
    // 调用并得到返回值
    Object returnValue = pjp.proceed(methodArgs);
    ...
    return returnValue;
}

除了对 控制器 上面来配置AOP, 还通过 过滤器 / 拦截器 来管理:

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题