分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>
