spring boot拦截器实现IP黑名单实例代码

网友投稿 328 2023-05-20


spring boot拦截器实现IP黑名单实例代码

前言

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

功能需求

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

知识记录

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; // 日期类型,格式:dzcvkvHrjsyyyy-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 findByIp(String ip);

// 添加记录

int addBlackList(@Param("blackList") BlackList blackList);

}

实现 HandlerInterceptor 接口

public class URLInterceptor implements HandlerInterceptor {

@Autowired

BlackListDao blackListDao;

private Map redisTemplate = new HashMap();

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 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(HttpServletRhttp://equest 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";

}

项目参考地址 : https://github.com/FunriLy/springboot-study/tree/master/%E6%A1%88%E4%BE%8B8


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信小程序 request接口的封装实例代码
下一篇:Java计算两个程序运行时间的实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~