[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 ...
随机推荐
- 51Nod 1421
1421 最大MOD值 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以是同一个) ai,aj ,使得 ai mod aj 最大并且 ai ≥ aj. Input 单组测试数据. 第一行包含 ...
- 经典DFS问题 oilland 连通块
#include "iostream" #include "cstdio" using namespace std; ][]={{,},{,-},{,},{-, ...
- HDU2546饭卡---(DP 经典背包)
http://acm.hdu.edu.cn/showproblem.php?pid=2546 饭卡 Time Limit: 5000/1000 MS (Java/Others) Memory L ...
- CSS3 3D 转换
CSS3 允许您使用 3D 转换来对元素进行格式化. 在本章中,您将学到其中的一些 3D 转换方法: rotateX() rotateY() rotateX() 方法 rotateX()方法,围绕其在 ...
- Ring0层创建事件,Ring3层接收
在学习驱动过程中,一个很重要的内容就是Ring3层与Ring0层的通信,方法有很多种,互斥体,信号量,文件等等,用的比较普遍的,还是事件.所以在学习的过程中,做了一个简单的Demo,主要是体会一下方法 ...
- POJ2680(动态规划,大数)
Computer Transformation Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4548 Accepted ...
- glib windows下编译
记录的比较粗糙,但是绝对可行的 一些小的瑕疵以后再解决吧 (android版本的过几天再贴,移植到android已经通过) msys+mingw包下载: http://sourceforge.net/ ...
- python学习笔记 async and await
用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异 ...
- C#后台调用js方法无效果,未解决。
this.Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "", "<script> ...
- 【转】java中的集合和数组
转载自:http://www.cnblogs.com/summers/p/4094260.html 数组Array和集合的区别: (1)数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型 ...