原文:http://www.cnblogs.com/xiaoyangjia/p/3762150.html?utm_source=tuicool

我们需要根据IP去限制用户单位时间的访问次数,防止刷手机验证码,屏蔽注册机等,使用注解就非常灵活了

1 定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
//最高优先级
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {
/**
*
* 允许访问的次数,默认值MAX_VALUE
*/
int count() default Integer.MAX_VALUE; /**
*
* 时间段,单位为毫秒,默认值一分钟
*/
long time() default 60000;
}

 2 实现注解

@Aspect
@Component
public class RequestLimitContract {
private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger");
@Autowired
private RedisTemplate<String, String> redisTemplate; @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)")
public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException { try {
Object[] args = joinPoint.getArgs();
HttpServletRequest request = null;
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof HttpServletRequest) {
request = (HttpServletRequest) args[i];
break;
}
}
if (request == null) {
throw new RequestLimitException("方法中缺失HttpServletRequest参数");
}
String ip = HttpRequestUtil.getIpAddr(request);
String url = request.getRequestURL().toString();
String key = "req_limit_".concat(url).concat(ip);
long count = redisTemplate.opsForValue().increment(key, 1);
if (count == 1) {
redisTemplate.expire(key, limit.time(), TimeUnit.MILLISECONDS);
}
if (count > limit.count()) {
logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]");
throw new RequestLimitException();
}
} catch (RequestLimitException e) {
throw e;
} catch (Exception e) {
logger.error("发生异常: ", e);
}
}
}

3 自定义Exception

public class RequestLimitException extends Exception {
private static final long serialVersionUID = 1364225358754654702L; public RequestLimitException() {
super("HTTP请求超出设定的限制");
} public RequestLimitException(String message) {
super(message);
} }

4 在Controller中使用

@RequestLimit(count=100,time=60000)
@RequestMapping("/test")
public String test(HttpServletRequest request, ModelMap modelMap) {
//TODO
}

[SpringMVC+redis]自定义aop注解实现控制器访问次数限制的更多相关文章

  1. [SpringMVC]自定义注解实现控制器访问次数限制

    我们需要根据IP去限制用户单位时间的访问次数,防止刷手机验证码,屏蔽注册机等,使用注解就非常灵活了 1 定义注解 @Retention(RetentionPolicy.RUNTIME) @Target ...

  2. SpringMVC中的常用注解

    RequestParam 作用: 用于  将请求参数区数据  映射到  功能处理方法的参数上. 属性: value  请求参数中的名称 required   请求参数中是否必须提供此参数. 默认值: ...

  3. Spring aop注解失效

    问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...

  4. 使用Redis+自定义注解实现接口防刷

    最近开发了一个功能,需要发送短信验证码鉴权,考虑到短信服务需要收费,因此对此接口做了防刷处理,实现方式主要是Redis+自定义注解(需要导入Redis的相关依赖,完成Redis的相关配置,gs代码,这 ...

  5. SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解

    SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解 博客分类: 跟开涛学SpringMVC   6.6.2.@RequestParam绑定单个请求参数值 @RequestParam用于 ...

  6. SpringMVC传统风格控制器和基于注解的控制器

    SpringMVC的DispatcherServlet 之前说过springMVC是使用Servlet作为控制器,就是这个用于调度的DispatcherServlet了.这个是servlet,可以根据 ...

  7. 【spring springmvc】springmvc使用注解声明控制器与请求映射

    目录 概述 壹:注解说明 贰:实现注解声明控制器与请求映射 一:使用controller 二:配置包扫描与视图解析器 1.配置包扫描 2.配置试图解析器 三:配置部署描述符 1.读取spring-mv ...

  8. [译]SpringMVC自定义验证注解(SpringMVC custom validation annotations)

    在基于SpringMVC框架的开发中,我们经常要对用户提交的字段进行合法性验证,比如整数类型的字段有个范围约束,我们会用@Range(min=1, max=4).在实际应用开发中,我们经常碰到一些自己 ...

  9. springMVC基于注解的控制器

    springMVC基于注解的控制器 springMVC基于注解的控制器的优点有两个: 1.控制器可以处理多个动作,这就允许将相关操作写在一个类中. 2.控制器的请求映射不需要存储在配置文件中.使用re ...

随机推荐

  1. 【BZOJ2818】Gcd [莫比乌斯反演]

    Gcd Time Limit: 10 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 给定整数N,求1<=x,y&l ...

  2. [转]华 使用npm安装一些包失败了的看过来(npm国内镜像介绍)

     发布于 5 年前  作者 wppept  275957 次浏览  最后一次编辑是 1 年前 这个也是网上搜的,亲自试过,非常好用! 镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置 ...

  3. bugscan泄露代码解密

    #{文件名:decode key} dekey_dict= {'expback_64pyc_dis.py': 'ef632082c7620cf54876da74a1660bfb9c06eb94549b ...

  4. Selenium菜鸟手册

    转自: http://www.iselenium.com/read.php?tid=458 首先声明我还是一只很菜的菜鸟,学习Selenium一个来月而已,发这个帖子是想利用我这块板砖引出真正的玉来, ...

  5. Spring MVC的静态和动态概念

    MVC模式: 图释:用户请求通过HTTP协议到达Front controller,Front controller把请求送给Controller,Controller了解业务逻辑细节并且调用业务逻辑数 ...

  6. 【反演复习计划】【bzoj2818】gcd

    就是之前的2820的升级版. 把暴力枚举素数改成预处理就随便A了. #include<bits/stdc++.h> #define N 10000005 #define ll long l ...

  7. EAScript 2016的新增语法(1)

    1)let 语法,这个和var的声明类似,但是,只存在于其所在的代码块里. 举例: var x=1 console.log(x) { let x=2 console.log(x) } console. ...

  8. 对数据访问层的重构(及重构中Perl的应用)

    以前上学的时候,听到“一个学生在毕业后刚刚开始编程的头几年中,写出的代码多半是垃圾”这样的说法,均不屑一顾.现在工作一年多了,越发感觉自己代码中疏漏处甚多,故近来常做亡羊补牢的重构之举.拿自己4个月前 ...

  9. 构建maven动态web 工程

    项目构建 总体参考: http://www.java2blog.com/2015/09/how-to-create-dynamic-web-project-using.html https://sta ...

  10. list 迭代器随机范围内移动

    Increments an iterator by a specified number of positions. template<class InputIterator, class Di ...