拦截器实现IP黑名单

前言

最近一直在搞 Hexo+GithubPage 搭建个人博客,所以没怎么进行 SpringBoot 的学习。所以今天就将上次的”?秒防刷新”进行了一番修改。上次是采用注解加拦截器(@Aspect)来实现功能的。但是,如果需求是一个全局的拦截器对于大部分URL都进行拦截的话,自己一个个加显然是不可能的。而且上次的拦截器对于Controller的参数有所要求,在实际他人引用总是显得不方便。所以,这次使用了继承HandlerInterceptor来实现拦截器。

功能需求

对于项目中某类URL进行拦截,若用户在短时间内大量访问该链接,则将用户IP列入黑名单,禁止用户访问网页。(同时,可以使用@Async来创建定时任务帮用户解禁。)

准备

?秒防刷新的业务逻辑

博客地址 : http://blog.csdn.net/u011244202/article/details/54783337
项目参考地址 : https://github.com/FunriLy/springboot-study/tree/master/%E6%A1%88%E4%BE%8B5

SpringBoot+Druid+MyBatis

博客地址 : http://blog.csdn.net/u011244202/article/details/54709060
项目参考地址 : https://github.com/FunriLy/springboot-study/tree/master/%E6%A1%88%E4%BE%8B1

知识记录

Spring 的拦截器
HandlerInterceptor 的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。我们不能通过拦截器修改request内容,但是可以通过抛出异常(或者返回false)来暂停request的执行。

配置拦截器也很简单,Spring 为此提供了基础类WebMvcConfigurerAdapter ,我们只需要重写addInterceptors 方法添加注册拦截器。

实现自定义拦截器只需要3步:
1、创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
2、创建一个 Java 类继承 WebMvcConfigurerAdapter,并重写 addInterceptors 方法。
3、实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。

正式开工

IP工具类

由于不清楚用户代理,最好能使用一个工具类来来获取用户真实IP。这个Google就能找到,我就不贴代码了。

数据库

我使用的是MySQL数据库,持久层框架为MyBatis。具体可参考”准备”步骤。
我在”myboot”数据库中创建一张表”blaclist”,属性如下:

字段名 解释
id 记录的id
ip 用户真实IP
iptime IP被锁时间

实体类

public class BlackList {

    private int id;
private String ip;
private Date iptime; // 日期类型,格式:yyyy-MM-dd HH:mm:ss
//构造器
public BlackList() {
} public BlackList(String ip, Date iptime) {
this.ip = ip;
this.iptime = iptime;
}
// get && set 方法
}

Dao层

注意XML配置与对应实体配置(省略)。

@Mapper
public interface BlackListDao {
// 根据IP来查找记录
List<BlackList> findByIp(String ip);
// 添加记录
int addBlackList(@Param("blackList") BlackList blackList);
}

实现 HandlerInterceptor 接口

public class URLInterceptor implements HandlerInterceptor {

    @Autowired
BlackListDao blackListDao; private Map<String, Integer> redisTemplate = new HashMap<String, Integer>();
private static final Logger logger = LoggerFactory.getLogger(URLInterceptor.class); //在请求处理之前进行调用(Controller方法调用之前)
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
return true;
} //请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
String ip = IPAddressUtil.getClientIpAddress(httpServletRequest);
List<BlackList> blackLists = blackListDao.findByIp(ip);
if (blackLists == null || blackLists.size() == 0){
urlHandle(httpServletRequest, 5000, 10);
} else {
//强制控制跳转
modelAndView.setViewName("/errorpage/error.html");
}
} //在整个请求结束之后被调用
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } public void urlHandle(HttpServletRequest request, long limitTime,int limitCount) throws RequestLimitException {
/**
* 省略业务逻辑部分,参考"准备"步骤
*/
if (count > limitCount){ //符合锁定条件
Calendar calendar = Calendar.getInstance();
Date iptime=calendar.getTime();
BlackList blackList = new BlackList(ip, iptime);
blackListDao.addBlackList(blackList);
throw new RequestLimitException();
}
}
}

WebMvcConfigurerAdapter类

配置 spring mvc的拦截器 WebMvcConfigurerAdapter。

@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Bean //把我们的拦截器注入为bean
public HandlerInterceptor getMyInterceptor(){
return new URLInterceptor();
} @Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则, 这里假设拦截 /url 后面的全部链接
// excludePathPatterns 用户排除拦截
registry.addInterceptor(getMyInterceptor()).addPathPatterns("/url/**");
super.addInterceptors(registry);
}
}

Controller类

    @RequestMapping("/url/test")
@ResponseBody
public String URLtest() {
return "success";
}

spring boot 学习(十二)拦截器实现IP黑名单的更多相关文章

  1. springMVC学习 十二 拦截器

    一 拦截器概述 拦截器技术比较像java web技术中的过滤器技术,都是发送 请求时被拦截器拦截,在控制器的前后添加额外功能.但是和Spring中的Aop技术是由区别的.AOP 在特定方法前后扩充(一 ...

  2. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  3. Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客

    ==他的博客应该不错,没有细看 Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客 http://blog.csdn.net/u012706811/article/det ...

  4. Springboot拦截器实现IP黑名单

    Springboot拦截器实现IP黑名单 一·业务场景和需要实现的功能 以redis作为IP存储地址实现. 业务场景:针对秒杀活动或者常规电商业务场景等,防止恶意脚本不停的刷接口. 实现功能:写一个拦 ...

  5. spring boot 学习(十四)SpringBoot+Redis+SpringSession缓存之实战

    SpringBoot + Redis +SpringSession 缓存之实战 前言 前几天,从师兄那儿了解到EhCache是进程内的缓存框架,虽然它已经提供了集群环境下的缓存同步策略,这种同步仍然需 ...

  6. Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证

    本文通过一个简易安全认证示例的开发实践,理解过滤器和拦截器的工作原理. 很多文章都将过滤器(Filter).拦截器(Interceptor)和监听器(Listener)这三者和Spring关联起来讲解 ...

  7. Spring Boot 优雅的配置拦截器方式

    https://my.oschina.net/bianxin/blog/2876640 https://cs.xieyonghui.com/java/55.html 其实spring boot拦截器的 ...

  8. Spring Boot学习笔记二

    Spring Boot入门第二篇 第一天的详见:https://www.cnblogs.com/LBJLAKERS/p/12001253.html 同样是新建一个pring Initializer快速 ...

  9. Springboot 系列(六)Spring Boot web 开发之拦截器和三大组件

    1. 拦截器 Springboot 中的 Interceptor 拦截器也就是 mvc 中的拦截器,只是省去了 xml 配置部分.并没有本质的不同,都是通过实现 HandlerInterceptor ...

随机推荐

  1. React 回忆录(一)为什么使用 React?

    Hi 各位,欢迎来到 React 回忆录!

  2. Linux命令中:rsync和cp之间的区别

    rsync:只拷贝那些更新的文件: cp -u:也可以实现类似效果: 两者都基本可以满足备份的需求: 只是一般情况下,用rsync做这类备份之类的事情,更多见: 在备份的操作中,拷贝,过期文件的删除是 ...

  3. Big Number-Asia 2002, Dhaka (Bengal) (计算位数)题解

    Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  4. 【jdk源码分析】java.lang.Appendable

    1.概述 public interface Appendable 能够被添加 char 序列和值的对象.如果某个类的实例打算接收取自 Formatter 的格式化输出,那么该类必须实现 Appenda ...

  5. The way to Go(4): Go runtime及解释器

    Reference: Github: Go Github: The way to Go Go runtime Go runtime: 尽管 Go 编译器产生的是本地可执行代码,这些代码仍旧运行在 Go ...

  6. windows 模拟用户会话创建进程

    在渗透当中,经常会碰到这样的问题.一个机器,机器上好几个用户,或者域内,想让某个机器的某个会话执行你想要执行的程序,或者中马,以当前会话来上线. 现在模拟如下的一个情况: 严格的DMZ,内网--> ...

  7. 尽量少用memcpy, 多用strcpy

    一般情况下,童鞋们都喜欢用memcpy函数去传递或者备份一个数据块.这样用起来是没有多大问题的,可是如果你要用其拷贝可见字符串的时候,就用问题了,你可能拷贝到的不是你希望的字符串,甚至是原来字符串的的 ...

  8. WiscKey: Separating Keys from Values in SSD-Conscious Storage [读后整理]

    WiscKey: Separating Keys from Values in SSD-Conscious Storage WiscKey是一个基于LSM的KV存储引擎,特点是:针对SSD的顺序和随机 ...

  9. Python 实现协程

    协程的概念 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程.(其实并没有说明白~) 我觉得单说协程,比较抽象,如果对线程有一定了解的话,应该就比较 ...

  10. ros 使用命令测试topic

    发布话题 $ rostopic pub -r /chatter std_msgs/String "test" 输出数据: $ rostopic echo /chatter data ...