SpringBoot中实现拦截器级别的URl访问过快拦截,并利用JPA实现IP黑名单的功能。
2016-09-26 17:15
916 查看
今天给大家介绍一下SpringBoot中实现拦截器级别URl过快访问拦截,并利用JPA实现IP黑名单的功能。
上一节中已经将中已经介绍了在控制器层面上面的URL拦截,这一节则侧重于网站全局式的拦截。就是不管输入什么URL地址都会进行过滤,判断是否存在URL访问过快的情况发生。因为本文会用到前面已经讲过的JPA和拦截器技术,所以接下来就不对JPA和拦截器的实现过程进行认真的讲解了。有需要的朋友可以看我以前写的博客案例。步骤一:下面先新建一张IP黑名单表,表的结构如下所示:
步骤二:新建一个实体类,并于黑名单表相映射。例子代码如下:
package example.entity; import javax.persistence.*; import java.util.Date; @Entity @Table(name = "blacklist") public class Blacklist { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "ip", nullable = true, length = 30) private String ip; @Temporal(TemporalType.TIMESTAMP) private Date iptime; // 日期类型,格式:yyyy-MM-dd HH:mm:ss public Blacklist() { } public Blacklist(String ip, Date iptime) { this.ip = ip; this.iptime = iptime; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public Date getIptime() { return iptime; } public void setIptime(Date iptime) { this.iptime = iptime; } }
步骤三:新建一个黑名单的数据库操作类,也就是dao类。例子代码如下:
package example.dao; import example.entity.Blacklist; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import javax.transaction.Transactional; import java.util.List; @Transactional @Repository public interface BlacklistDao extends JpaRepository<Blacklist, Integer> { public List<Blacklist> findByIp(String ip); }步骤四:新建一个过滤器类,并实现对URL访问过快的拦截,并将那些攻击者的IP加入黑名单中去。例子代码如下:
package example.Interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import example.controller.exception.RequestLimitException; import example.controller.limit.RequestLimit; import example.controller.limit.RequestLimitContract; import example.dao.BlacklistDao; import example.entity.Blacklist; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Service; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import java.util.*; /** * 自定义拦截器1 * * @author 林志强(208017534) * @myblog www.wolzq.com * @create 2016年9月20日 */ public class URLInterceptor implements HandlerInterceptor { @Autowired private BlacklistDao blacklistDao; private Map<String, Integer> redisTemplate=new HashMap<String,Integer>(); private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { String ip = request.getLocalAddr(); List<Blacklist> blackList =blacklistDao.findByIp(ip); if(blackList==null || blackList.size()==0){ urlHandle(request,10000,10); }else{ modelAndView.setViewName("/errorpage/error"); } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } public void urlHandle(HttpServletRequest request, long limitTime,int limitCount) throws RequestLimitException { try{ String ip = request.getLocalAddr(); String url = request.getRequestURL().toString(); String key = "req_limit_".concat(url).concat(ip); if(redisTemplate.get(key)==null || redisTemplate.get(key)==0){ redisTemplate.put(key,1); }else{ redisTemplate.put(key,redisTemplate.get(key)+1); } int count = redisTemplate.get(key); if (count > 0) { Timer timer= new Timer(); TimerTask task = new TimerTask(){ @Override public void run() { redisTemplate.remove(key); } }; timer.schedule(task, limitTime); } if (count > limitCount) { addHostHandle(ip); throw new RequestLimitException(); } } catch (RequestLimitException e) { throw e; } catch (Exception e) { logger.error("发生异常: ", e); } } public void addHostHandle(String ip){ Calendar calendar = Calendar.getInstance(); Date iptime=calendar.getTime(); Blacklist blacklist=new Blacklist(ip,iptime); blacklistDao.save(blacklist); } }步骤五:在拦截器添加类中加入bean方法,否则JPA不能自动注入成功,因为容器还未加载就已经实现拦截器的功能了。例子代码如下:
package example.configuration; import example.Interceptor.ErrorInterceptor; import example.Interceptor.URLInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Bean public HandlerInterceptor getMyInterceptor(){ return new URLInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { // 多个拦截器组成一个拦截器链 // addPathPatterns 用于添加拦截规则 // excludePathPatterns 用户排除拦截 registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**"); super.addInterceptors(registry); } }步骤六:在html资源文件下面新建一个错误界面,用于黑名单用户的跳转操作。例子代码如下:
<html> <head> <meta charset="UTF-8"/> <title>Title</title> </head> <body> <h1>您已经被列入黑名单中,请及时和管理员联系,接触黑名单限制。。。。</h1> </body> </html>这样就已经实现了拦截器级别URl访问过快拦截,并利用JPA实现IP黑名单的功能,是不是特别简单呀。
如果大家想要源代码或者对博客有啥异议都可以加我QQ:208017534 欢迎打扰哦!!!
相关文章推荐
- Spring事务配置的五种方式
- Eclipse安装JD-Eclipse反编译插件
- Spring事务管理
- Leetcode刷题记——3. Longest Substring Without Repeating Characters
- Java mail基础使用 (一)
- Struts+Hibernate+Spring学习心得(1)Struts
- JNI对数组赋值排序,创建数组并返回给Java
- Spring---那常用的注解
- java登录验证码实现代码
- java浅说(1):文件File的创建
- Spring ioc
- java 执行bat批处理文件 并关闭cmd窗口
- 任务1:搭建Java开发环境
- Java高并发,如何解决,什么方式解决
- 【JavaWeb-13】文件上传DiskFileItemFactory、ServletFileUpload以及注意事项、文件下载及注意事项
- Java控制语句 标签的用法
- spring mvc static url
- day_03 使用Eclipse工具创建一个类并执行结果
- java代码检查是否为有效ip地址
- Spring事务传播性与隔离级别