根目录如下:
package filter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
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.annotation.WebFilter;
/**
* Servlet Filter implementation class MyFilter
*/
@WebFilter("/*")
public class MyFilter implements Filter {
/*
* 步骤:1.从application域中拿到map
* 2.获取用户访问时的ip地址
* 3.拿到ip地址在map中进行判断 如果已经存在使值+1 如果不存在设置值为1
*
*/
private int MAX_NUM = 5;
private FilterConfig fconfig;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("正在拦截");
ServletContext application = fconfig.getServletContext();
Map<String,Integer> map = (LinkedHashMap<String,Integer>)application.getAttribute("map");
System.out.println(map);
String Ip = request.getRemoteAddr();
if(map.containsKey(Ip)){
int value = (Integer)map.get(Ip);
if(value>=MAX_NUM){
request.getRequestDispatcher("/error.jsp").forward(request, response);
}
map.put(Ip, ++value);
}else{
map.put(Ip, 1);
}
System.out.println(map);
application.setAttribute("map", map);
chain.doFilter(request, response);//进行放行操作
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("我被初始化了");
this.fconfig = fConfig;
}
}
package listener;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class MyListener
*
*/
@WebListener
public class MyListener implements ServletContextListener {
/*
* 步骤:ServletContextListener的生命周期方法init()在服务器创建时会被调用
* 1.我们可以在init()中来创建一个map用来保存客户访问的Ip和访问次数count。
* 2.保存map到ServletContext域中
*/
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("listener被初始化");
Map<String,Integer> map = new LinkedHashMap<String,Integer>();
ServletContext application = arg0.getServletContext();
application.setAttribute("map", map);
}
public void contextDestroyed(ServletContextEvent arg0) {
}
}
a.jsp
</head>
<body>
<h1>你的ip已经被记录了</h1>
</body>
b.jsp
<body>
<table align="center" width="60%">
<tr>
<th>IP</th>
<th>访问次数</th>
</tr>
<c:forEach items="${applicationScope.map}" var="entry">
<tr>
<td>${entry.key }</td>
<td>${entry.value }</td>
</tr>
</c:forEach>
</table>
</body>
error.jsp
<body>
<h1>你的访问次数已到,禁止访问页面</h1>
</body>
注意:①Servletcontext的生命周期监听器和Filter的监听器一样都是在服务器创建就进行初始化工作,
在Filter的Filterconfig中可以拿到Serveltcontext对象
②我们通常在Listener的 生命周期方法创建map记录数据,原因:在Filter中创建数据了,可能监听多个网页或Servlet而其他的并不需要map存放数据,耦合性更高
3,当用户访问超过自定义的最大访问次数后,会请求转发到error.jsp显示。