保洁阿姨
50+年前端设计经验
悠悠博客
usuuu.com
保洁阿姨
50+年前端设计经验
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HasApiLimit {
/**
* 时间范围(分钟)
*/
int seconds();
/**
* 限制的次数
*/
int maxCount();
}
@Aspect
@Component
public class ApiLimit {
/**
* 定义一个切点(通过注解)
*/
@Pointcut("@annotation(com.blog.aop.has.HasApiLimit)")
public void HasApiLimit() {
}
/**
* Aop切面方法
*
* @param joinPoint 切点
*/
@Before("HasApiLimit()")
public void before(JoinPoint joinPoint) {
//获取当前请求的方法上的注解中设置的值
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//反射获取当前被调用的方法
Method method = signature.getMethod();
//获取方法中的注解,看是否有该注解
HasApiLimit hasApiLimit = method.getDeclaredAnnotation(HasApiLimit.class);
int seconds = hasApiLimit.seconds();
int maxCount = hasApiLimit.maxCount();
//获取请求相关信息
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String ip = getIpAddr(request);
String api = request.getRequestURI();
//拼接redis key
String key = "HasApiLimit:" + ip + ":" + api;
//判断key是否存在,如果不存在,则说明是第一次访问
if (!RedisUtils.hasKey(key)) {
RedisUtils.set(key, 1, seconds, TimeUnit.MINUTES);
} else {
//key存在,则获取当前访问次数
int count = Integer.parseInt(String.valueOf(RedisUtils.get(key)));
if (count >= maxCount) {
//超过了限制次数,返回错误信息
throw new BusinessException("使用频率过高," + seconds + "分钟后再试");
} else {
RedisUtils.increment(key, 1);
}
}
}
/**
* 获取真实IP地址
*
* @param request HttpServletRequest
*/
private String getIpAddr(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.getRemoteAddr();
}
return ip;
}
}
@HasApiLimit(seconds = 3, maxCount = 1)
@HasRoleAuth("api:comments:create")
@PostMapping("/create")
public R<?> create(@RequestBody CommentBo commentBo) {
commentService.create(commentBo);
return R.ok(null, "评论成功");
}
要获取真实的IP地址
因此需要在Nginx或Apache等Web服务器中配置反向代理
可以在Web服务器中添加如下配置:
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
站点公告
NoticeWeb前后端交流群:70888820
QQ号523179414(姓:郑)狗骗子,谢绝访问
热门文章
Host3139 次围观
3631 次围观
3879 次围观
1963 次围观
6666 次围观
4161 次围观
1854 次围观
1060 次围观