分IP统计访问次数即网站统计每个IP地址访问本网站的次数。
分析
因为一个网站可能有多个页面,无论哪个页面被访问,都要统计访问次数,所以使用过滤器最为方便。
因为需要分IP统计,所以可以在过滤器中创建一个Map,使用IP为key,访问次数为value。当有用户访问时,获取请求的IP,如果IP在Map中存在,说明以前访问过,那么在访问次数上加1,即可;IP在Map中不存在,那么设置次数为1。
那么问题来了!
问题一:为什么使用Map存放?
Map是一个由键值对组成的数据结构,其中所有的key组成一个set集合,所有的value组成一个List集合。且在集合中每个键是唯一的,保持了查找结果的一致性。
问题二:把Map放在什么域中?
因为Map中记录的是访问相关数据,因此要在服务器开启时就要创建Map,记录数据。要把这个Map存放到ServletContext中!
1. 存储数据使用:Map,其中ip为键,访问次数为值。
IP 次数
192.168.51.2 66
192.168.51.4 88
2. 把Map放到ServletContext中
3. 使用过滤器来完成统计!
* 获取ServletContext中的map
> Map map = (Map)sc.getAttribute("map");
> if(map == null) { map = new HashMap(); sc.setAttribute("map", map);}
* 获取当前请求的IP地址:request.getRemoteAddr()
* 使用IP为键,查看map中是否存在这个键
* 如果IP在Map中存在,说明不是第一次访问,那么获取访问次数,再加1,然后保存回到map中
* 如果IP在Map中不存在,说明是第一次访问,向map添加键值,键为IP,值为1。
4. 建立index.jsp,这个页面会获取ServletContext中的map,然后循环显示。
代码:
IpFilter.java
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; /** *分IP统计访问次数 */ public class IpFilter implements Filter { private FilterConfig config; public void init(FilterConfig config) throws ServletException { this.config=config; } /* * 1. 获取Map * 2. 获取请求IP * 3. 查看IP在Map中是否存在 * 4. 如果存在,把访问次数+1,再保存回去 * 5. 如果不存在,添加键值,键为IP,值为1 * 6. 放行! */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //获取ServletConfig ServletContext sc = config.getServletContext(); //获取ServletContext中的map Map<String,Integer> map=(Map<String, Integer>) sc.getAttribute("map"); //如果map不存在,说明这是第一次被访问 if(map==null){ //创建map map=new LinkedHashMap<String,Integer>(); } //获取请求ip String ip = request.getRemoteAddr(); //判断map中是否存在这个ip if(map.containsKey(ip)){ //如果ip存在,说明这个IP已经访问过本站 // 获取访问次数 Integer count = map.get(ip); //把访问次数+1 count++; //把新的访问次数保存回去 map.put(ip, count); }else{ //因为这个IP是第一次访问,所以值为1 map.put(ip, 1); } //把map放入ServletContext中 sc.setAttribute("map", map); //放行 chain.doFilter(request, response); } public void destroy() { } }
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP ‘index.jsp‘ starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>分IP统计</h1> <table border="1" width="60%"> <c:forEach items="${applicationScope.map }" var="entry"> <tr> <th>ip</th> <th>数量</th> </tr> <tr> <td>${entry.key }</td> <td>${entry.value }</td> </tr> </c:forEach> </table> </body> </html>