首先,定义一个实体类UserIp
private String ip; //用户ip
private Integer count; //访问次数
private Long ft; //第一次访问时间
过滤器IpFilter
/**
* @author 小姜
* @version V1.0
* @date 2021/9/15 19:12
* @phone
*/
@WebFilter(filterName = "ipFilter",urlPatterns = "/*")
public class IpFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//类型转换
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//设置响应的字符编码
response.setContentType("text/html;charset=utf-8");
//接收请求的客户机ip地址
String ip = request.getRemoteAddr();
System.out.println(ip);
//根据ip从session中获取ip对象
HttpSession session = request.getSession();
UserIp userIp = (UserIp) session.getAttribute(ip);
System.out.println(userIp);
if (userIp == null) { //说明当前ip还没有访问过,记录这个ip,放到session中
UserIp u = new UserIp();
u.setCount(1);
u.setFt(System.currentTimeMillis());
u.setIp(ip);
session.setAttribute(ip,u);
}else{ //说明该ip是之前访问过的
//获取这个ip第一次访问的时间
Long ft = userIp.getFt();
if(ft == null){
response.getWriter().write("时间请求为空");
return;
}else{
//如果当前时间距离这个ip上一次的请求时间超过了5秒,就重置请求信息为第一次,请求通过
Long time = System.currentTimeMillis() - userIp.getFt();
System.out.println(time);
if (time > 5000){
userIp.setCount(1);
userIp.setFt(System.currentTimeMillis());
userIp.setIp(ip);
session.setAttribute(ip,userIp);
}else{
//说明此次请求距离上一次请求的时间小于5秒
//判断一下这个ip请求的次数
if(userIp.getCount() >= 10){
//设置这个ip的上一次请求时间是15秒之后
//15秒之后再判断当前时间距离这个ip的上一次请求时间的时间间隔
//如果是5秒以上的话,就可以正常访问了,这样加起来就刚好是封停了20秒
//如果不是5秒以内的话就需要重新设置这个ip的请求时间为15秒之后
userIp.setFt(System.currentTimeMillis() + 15000);
response.getWriter().write("<h2 style='color:red;text-align:center'>请求太快了,您的ip已经被封停,20秒后重试<br />期间如果继续访问会重新计算20秒解封时间</h2>");
return;
}else{
//请求时间间隔小于5秒,且请求次数小于10次
userIp.setCount(userIp.getCount() + 1);
userIp.setFt(System.currentTimeMillis());
userIp.setIp(ip);
session.setAttribute(ip,userIp);
}
}
}
}
filterChain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
实现效果