[SpringMVC+redis]自定义aop注解实现控制器访问次数限制
原文: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注解实现控制器访问次数限制的更多相关文章
- [SpringMVC]自定义注解实现控制器访问次数限制
我们需要根据IP去限制用户单位时间的访问次数,防止刷手机验证码,屏蔽注册机等,使用注解就非常灵活了 1 定义注解 @Retention(RetentionPolicy.RUNTIME) @Target ...
- SpringMVC中的常用注解
RequestParam 作用: 用于 将请求参数区数据 映射到 功能处理方法的参数上. 属性: value 请求参数中的名称 required 请求参数中是否必须提供此参数. 默认值: ...
- Spring aop注解失效
问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...
- 使用Redis+自定义注解实现接口防刷
最近开发了一个功能,需要发送短信验证码鉴权,考虑到短信服务需要收费,因此对此接口做了防刷处理,实现方式主要是Redis+自定义注解(需要导入Redis的相关依赖,完成Redis的相关配置,gs代码,这 ...
- SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解
SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解 博客分类: 跟开涛学SpringMVC 6.6.2.@RequestParam绑定单个请求参数值 @RequestParam用于 ...
- SpringMVC传统风格控制器和基于注解的控制器
SpringMVC的DispatcherServlet 之前说过springMVC是使用Servlet作为控制器,就是这个用于调度的DispatcherServlet了.这个是servlet,可以根据 ...
- 【spring springmvc】springmvc使用注解声明控制器与请求映射
目录 概述 壹:注解说明 贰:实现注解声明控制器与请求映射 一:使用controller 二:配置包扫描与视图解析器 1.配置包扫描 2.配置试图解析器 三:配置部署描述符 1.读取spring-mv ...
- [译]SpringMVC自定义验证注解(SpringMVC custom validation annotations)
在基于SpringMVC框架的开发中,我们经常要对用户提交的字段进行合法性验证,比如整数类型的字段有个范围约束,我们会用@Range(min=1, max=4).在实际应用开发中,我们经常碰到一些自己 ...
- springMVC基于注解的控制器
springMVC基于注解的控制器 springMVC基于注解的控制器的优点有两个: 1.控制器可以处理多个动作,这就允许将相关操作写在一个类中. 2.控制器的请求映射不需要存储在配置文件中.使用re ...
随机推荐
- HDU5748---(记录每个元素的 最长上升子序列 nlogn)
分析: 给一个序列,求出每个位置结尾的最长上升子序列 O(n^2) 超时 #include "cstdio" #include "algorithm" #def ...
- Python基础(4)_集合、布尔类型
一.集合 集合的作用一:关系运算集合的作用二:去重 定义集合:集合内的元素必须是唯一的:集合内的元素必须是可hash的,也是就不可变类型:集合是无序的 s={'egon',123,'egon','1' ...
- tr/td
在HTML中,tr代表行,td代表列. 说明: 1.tr与td必须一起使用,并且输入的内容必须在td里面: 2.td必须在tr里面,表示在一行中的列: 3.在一个tr里面,有x个td,就表示在这一行里 ...
- Oracle exp
--导出表exp userid=hr/oracle123 tables=employees direct=y file=/u01/employees.dmp log=/u01/employees.lo ...
- 原型和JS内置对象
原型 1.定义 每一个对象都有原型 原型仍然是一个对象 模拟实现面向对象的继承性 2.原型链 对象的原型还有原型 对象除了可以使用自有属性还可以继承原型上的属性 3.获取原型 对象.__proto__ ...
- Java==与equals方法的区别
摘自:http://www.cnblogs.com/dolphin0520/p/3592500.html 1.对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等: 如果作用于引 ...
- [ LDAP ] LDAP服务搭建及应用
ldap 搭建及应用 node1: 192.168.118.14node2: 192.168.118.25 ldap server : 192.168.118.14 1. 安装LDAP服务器 [roo ...
- 图的遍历[DFS][BFS]
#include<iostream> #include<iostream> #include<cstring> #include<queue> #inc ...
- 对tmemorystream的一些改进_delphi教程
http://www.cnblogs.com/linyawen/archive/2010/12/11/1903072.html 怎么又是关于Stream的,呵呵,应该说只是最近比较关心程式的效率问题, ...
- php关于private、protected、public的区别
一句话总结: private 自己的 protected 父亲的 public 大众的