java拦截ip和限制ip访问接口的次数

转载请标明出处:
https://blog.csdn.net/weixin_41965979/article/details/90720405
本文出自付付讶的博客

          这两天因为公司需求需要加一个限制ip请求次数的功能,限制某些ip一天只能访问10次,现在总结一下(因为是老项目所以用的是servlet)

用到的jar包:commons-lang3-3.8.1.jar

用到的技术:过滤器(Filter)

思路:数据库里创建2字段,一个ip,一个请求次数,并给他们填上值:ip写上你要拦截的ip,次数全部填0;

           代码里创建一个Map,用来存放要拦截的ip地址,通过反向代理得到当前请求的ip,拿到ip查询当前次数,然后判断Map             里包不包括当前请求的Ip地址,有的话则计算请求次数,然后在数据库里添加一个定时器每天0点清空次数                (https://blog.csdn.net/weixin_41965979/article/details/90700370这篇文章有写数据库怎么添加一个自动定时器),这样的话次数都是当天的,最后判断次数大于10就给它跳错误页面就行了;

下面直接上代码,有问题可以留言交流;

配置文件(web.xml): 

   
      
       IPFilter  
       com.roadLeader.filter.IPFilter  
      
      
       IPFilter  
       /*  
      

 新建一个过滤器类(IPFilter):

import java.io.IOException;  
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;  
import java.util.Map.Entry;
import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletContext;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.apache.commons.lang3.StringUtils;
import com.roadLeader.jdbc.LinkDB;
/** 
 * @Description 自定义过滤器,用来判断IP访问次数是否超限。
* @author fling * @date 2019年5月28日 * @since JDK : 1.7 */ public class IPFilter implements Filter{ private FilterConfig config; //统计ip请求次数 int count; Integer numbers; //存储ip Map ipMap=new HashMap(); @Override public void init(FilterConfig filterConfig) throws ServletException { this.config = filterConfig; //以下是我要拦截的ip(由于工作业务原因,不方便展示真实ip,以下全部用127.0.0.1代替,实际上 是5个不同的客户的ip,此ip跟数据库要对上哟) ipMap.put("127.0.0.1", count); ipMap.put("127.0.0.1", count); ipMap.put("127.0.0.1", count); ipMap.put("127.0.0.1", count); ipMap.put("127.0.0.1", count); } /** * @Description 核心处理代码 */ @SuppressWarnings("unchecked") @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; ServletContext context = config.getServletContext(); //得到当前请求的ip String ip = request.getHeader("X-Forwarded-For"); if (StringUtils.isNotEmpty(ip) && !"unKnow".equalsIgnoreCase(ip)) { //多次反向代理后会有多个ip值,第一个ip才是真实ip String[] ipList1 = ip.split(","); ip = ipList1[0]; } else { ip = request.getHeader("X-Real-IP"); if (StringUtils.isEmpty(ip) || "unKnown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } } //查询ip和次数 String aliIp=""; int number=0; try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Connection conn = new LinkDB().getConnection(); String sql = "SELECT number,ip FROM ipTable WHERE ip='"+ip+"'"; PreparedStatement pre = conn.prepareStatement(sql); ResultSet rs = pre.executeQuery(); while (rs.next()) { aliIp = rs.getString("ip"); number = rs.getInt("number"); }; conn.close(); } catch (Exception e) { e.printStackTrace(); } //判断如果包括当前请求ip则计算请求次数 if(ipMap.containsKey(ip)){ numbers = number+1; try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Connection conn = new LinkDB().getConnection(); String sql = "update ipTable set number=? where ip=?"; PreparedStatement pre = conn.prepareStatement(sql); pre.setInt(1, numbers); pre.setString(2, ip); pre.executeUpdate(); conn.close(); } catch (Exception e) { e.printStackTrace(); } }else{ ipMap.put(ip, 1); } context.setAttribute("ipMap", ipMap); chain.doFilter(request, response); //判断大于10次跳错误页面 if(numbers>10){ request.getRequestDispatcher("WEB-INF/error.jsp").forward(request, response); } } @Override public void destroy() { } }

测试:

      当我发送第一次请求时,数据库次数变成了1,这时应该响应成功(数据私密性这里打上马赛克);

java拦截ip和限制ip访问接口的次数_第1张图片

当我发送到第11次请求时 ,这时候数据库次数变成11,响应返回报错页面;

java拦截ip和限制ip访问接口的次数_第2张图片

你可能感兴趣的:(java,filter,ip,java)