注解+aop/拦截器实现防重复点击、机刷
来源:互联网 发布:淘宝卖鞋子的好店 编辑:程序博客网 时间:2024/06/09 18:54
拦截器实现
package com.qccr.cashcow.web.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.qccr.cashcow.biz.util.IpUtil;import com.qccr.cashcow.common.core.RedisCaches;import com.qccr.cashcow.common.core.StateCodes;import com.qccr.cashcow.common.exception.SystemServerException;import com.qccr.cashcow.common.util.Logs;import com.qccr.cashcow.web.core.HttpRequestContext;import com.qccr.cashcow.web.core.annotation.HttpLimit;/** * 访问限制 * * @author pys * * @date 2016年3月23日 下午7:57:44 */public class HttpLimitInterceptor extends HandlerInterceptorAdapter { private static final Logger logger = LoggerFactory.getLogger(HttpLimitInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (HandlerMethod.class.isInstance(handler)) { final HandlerMethod hm = ((HandlerMethod) handler); HttpLimit limit = hm.getMethodAnnotation(HttpLimit.class); if (limit != null) { String ip = getIpAddress(request); String url = request.getRequestURL().toString(); String key = "http_limit_".concat(url); int userId = HttpRequestContext.getClient().getUserId(); if (userId > 0) { key = key + userId; } else { key = key + ip; } long count = redisTemplate.opsForValue().increment(key, 1); System.out.println(count); if (count == 1) { redisTemplate.expire(key, limit.time(), limit.unit()); if (count == 1) { RedisCaches.expire(key, limit.time()); } if (count > limit.times()) { Logs.info("用户[" + (userId > 0 ? userId : ip) + "]访问地址[" + url + "]超过了限定的次数[" + limit.times() + "]", logger); throw new Exception("短时间内访问次数超出限制"); } } } return true; }private String getIpAddress(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; }}
aop实现
package com.qccr.cashcow.web.interceptor;import java.util.concurrent.TimeUnit;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import com.qccr.cashcow.common.core.StateCodes;import com.qccr.cashcow.common.exception.SystemServerException;import com.qccr.cashcow.common.util.Logs;import com.qccr.cashcow.web.core.annotation.HttpLimit;@Aspect@Componentpublic class HttpLimitContract { private static final Logger logger = LoggerFactory.getLogger(HttpLimitContract.class); @Autowired private RedisTemplate<String, String> redisTemplate; @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)") public void httpLimit(final JoinPoint joinPoint, HttpLimit limit) throws Exception { System.out.print("in:"); 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 SystemServerException(StateCodes.OPERATE_ERROR); } String ip = getIpAddress(request); String url = request.getRequestURL().toString(); String key = "http_limit_".concat(url).concat(ip); long count = redisTemplate.opsForValue().increment(key, 1); System.out.println(count); if (count == 1) { redisTemplate.expire(key, limit.time(), limit.unit()); } if (count > limit.times()) { Logs.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.times() + "]", logger); throw new Exception("短时间内访问次数超出限制"); } } private String getIpAddress(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; }}
HttpLimit 默认1分钟2次
package com.datatrees.loan.thirdparty.validator;import java.lang.annotation.*;import java.util.concurrent.TimeUnit;/** * 访问限制 * * @author pys * * @date 2016年3月23日 下午7:47:44 */@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface HttpLimit { long time() default 60 * 1000L; TimeUnit unit() default TimeUnit.MILLISECONDS; int times() default 2;}
阅读全文
0 0
- 注解+aop/拦截器实现防重复点击、机刷
- SpringMVC拦截器实现防重复提交
- spring boot 拦截器实现防重复提交
- spring AOP 注解实现登录权限拦截
- AOP的实现:Spring注解形式拦截
- 使用AOP拦截注解实现功能
- 2017.12.22 自定义注解、AOP、拦截器
- interceptor拦截器实现aop
- AOP/CGLIB学习:实现简单的注解权限系统(Annotation+拦截器)
- Spring Aop自定义注解拦截Controller实现日志管理
- 自定义注解,实现拦截器
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- URL中编码URL特殊字符
- centos 6安装zabbix agent
- 没有拿得出手的项目, 如何在面试/简历中为自己加分?
- 先验分布,后验分布,共轭分布的关系
- Linux:RPM 打包记录
- 注解+aop/拦截器实现防重复点击、机刷
- C# 文件夹的操作之选择文件夹对话框
- 静态代码块
- 「Object Detection」SSD: Single Shot MultiBox Detector
- TextView相关
- oracle之ROWNUM的用法(分页)以及ROWID的用法
- Oracle之内存结构详解(SGA+PGA)
- phantomjs selenium python 提示错误
- JAVA微信开发:如何获取accessToken