spring boot 学习(十二)拦截器实现IP黑名单
拦截器实现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黑名单的更多相关文章
- springMVC学习 十二 拦截器
一 拦截器概述 拦截器技术比较像java web技术中的过滤器技术,都是发送 请求时被拦截器拦截,在控制器的前后添加额外功能.但是和Spring中的Aop技术是由区别的.AOP 在特定方法前后扩充(一 ...
- spring boot / cloud (十二) 异常统一处理进阶
spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...
- Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客
==他的博客应该不错,没有细看 Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客 http://blog.csdn.net/u012706811/article/det ...
- Springboot拦截器实现IP黑名单
Springboot拦截器实现IP黑名单 一·业务场景和需要实现的功能 以redis作为IP存储地址实现. 业务场景:针对秒杀活动或者常规电商业务场景等,防止恶意脚本不停的刷接口. 实现功能:写一个拦 ...
- spring boot 学习(十四)SpringBoot+Redis+SpringSession缓存之实战
SpringBoot + Redis +SpringSession 缓存之实战 前言 前几天,从师兄那儿了解到EhCache是进程内的缓存框架,虽然它已经提供了集群环境下的缓存同步策略,这种同步仍然需 ...
- Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证
本文通过一个简易安全认证示例的开发实践,理解过滤器和拦截器的工作原理. 很多文章都将过滤器(Filter).拦截器(Interceptor)和监听器(Listener)这三者和Spring关联起来讲解 ...
- Spring Boot 优雅的配置拦截器方式
https://my.oschina.net/bianxin/blog/2876640 https://cs.xieyonghui.com/java/55.html 其实spring boot拦截器的 ...
- Spring Boot学习笔记二
Spring Boot入门第二篇 第一天的详见:https://www.cnblogs.com/LBJLAKERS/p/12001253.html 同样是新建一个pring Initializer快速 ...
- Springboot 系列(六)Spring Boot web 开发之拦截器和三大组件
1. 拦截器 Springboot 中的 Interceptor 拦截器也就是 mvc 中的拦截器,只是省去了 xml 配置部分.并没有本质的不同,都是通过实现 HandlerInterceptor ...
随机推荐
- 堆(Heap)
两种简单实现 第一种 链表 第一种实现利用链表存储数据,每次在表头插入元素:getMin 时,遍历一遍线性表找到最小的元素,然后将之删除.值返回.(getMax 同理). 链表的在头节点的插入和删除时 ...
- 编译安装vsftpd-3.0.2
编译安装vsftpd 首先下载源码包(我一般喜欢放在/home/test) 解压:tar -zxvf vsftpd-3.0.2.tar.gz 进入目录进行编译 cd vsftpd-3.0.2 编译之前 ...
- 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 2 章 答案
判断对错1.编写程序的好方法是立即键入一些代码,然后调试它,直到它工作.2.可以在不使用编程语言的情况下编写算法.3.程序在写入和调试后不再需要修改.4.Python 标识符必须以字母或下划线开头.5 ...
- python中的迭代器和生成器学习笔记总结
生成器就是一个在行为上和迭代器非常类似的对象. 是个对象! 迭代,顾名思意就是不停的代换的意思,迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次“迭代”,而 ...
- Python3基础 file with 配合文件操作
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- 三种常用的js数组去重方法
第一种是比较常规的方法 思路: 1.构建一个新的数组存放结果 2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比 3.若结果数组中没有该元素,则存到结果数组中 Array.pro ...
- Elasticsearch 基础概念知识
接近实时(NRT) Elasticsearch是一个接近实时的搜索平台.这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒). 集群(cluster) 一个集群就是由一个或多 ...
- POJ 2029 (二维树状数组)题解
思路: 大力出奇迹,先用二维树状数组存,然后暴力枚举 算某个矩形区域的值的示意图如下,代码在下面慢慢找... 代码: #include<cstdio> #include<map> ...
- [SpringBoot] - 发送带附件的邮件
<!--发送email依赖--> <dependency> <groupId>org.springframework.boot</groupId> &l ...
- js渐隐渐现透明度变化淡入淡出轮播图
js渐隐渐现透明度变化淡入淡出轮播图.焦点图 一些广告banner展示常见. (附件) <!DOCTYPE html> <html> <head> <meta ...