1. 程式人生 > >分IP統計訪問次數(監聽器負責建立map,過濾器負責統計,JSP負責顯示結果)

分IP統計訪問次數(監聽器負責建立map,過濾器負責統計,JSP負責顯示結果)

可以肯定的是,載入順序與它們在 web.xml 檔案中的先後順序無關。即不會因為 filter 寫在 listener 的前面而會先載入 filter。

最終得出的結論是:listener -> filter -> servlet

1是Listener中建立map

package cn.etc.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;

@WebListener
public class AListener implements ServletContextListener {

	/**
	 * 在伺服器啟動時建立Map,儲存到ServletContext
	 */
    public void contextInitialized(ServletContextEvent event)  { 
    	//建立Map
    	Map<String, Integer> map = new LinkedHashMap<String, Integer>();
    	//得到ServletContext
    	ServletContext application = event.getServletContext();
    	//把map儲存到application中
    	application.setAttribute("map", map);
    }
	
    public void contextDestroyed(ServletContextEvent event)  { 
    }
}

listener在web.xml中的配置:

<listener>

    <listener-class>cn.edu.AListener</listener-class>

</listener>

但是測試的時候不對在web.xml裡面配置監聽器,我是在Servlet裡面配置的

2是Filter中做統計

package cn.edu.filter;

import java.io.IOException;
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;

/**
 * 從application中獲取Map
 * 從request中得到當前客戶端的IP
 * 進行統計工作,結果儲存到Map中
 * @author pp
 *
 */
public class IpCountFilter implements Filter {

	private FilterConfig config;//config.getServletContext();//獲取上下文             

	/**
	 * 在伺服器啟動時就會執行本方法,而且本方法只執行一次!
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		this.config = fConfig;
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		/**
		 * 1.得到application中的map
		 * 2.從request中獲取當前客戶端的IP地址
		 * 3.檢視map中是否存在這個ip對應訪問次數,如果存在,把次數+1再儲存到map中
		 * 4.如果不存在這個Ip,那麼說明是第一次訪問本站,設定方位次數為1
		 */
		//1.得到application
		ServletContext application = config.getServletContext();//獲取上下文                    
		//從application中把map拿出來	  這個map是在AListener監聽器裡面											   map
		Map<String,Integer> map = (Map<String, Integer>)application.getAttribute("map");
		//2.獲取客戶端的ip地址
		String ip = request.getRemoteAddr();//不用強轉為HttpServletRequest,因為getRemoteAddr就在ServletRequest中
		//3.進行判斷
		if(map.containsKey(ip)){//這個ip在map中存在,說明不是第一次訪問
			int count = map.get(ip);//通過鍵ip獲得對應的值count
			count++;//加1
			map.put(ip, count);//把加1後的count和ip存入map中
		} else{//這個ip在map中不存在,說明是第一次訪問
			map.put(ip, 1);//第一次訪問的ip記為1了
		}
		
		//application.setAttribute("map", map);//可不存?! 引用!再把map放回到application中
		chain.doFilter(request, response);//放行
	}

	public void destroy() {
		//
	}

}

Filter在web.xml裡面的配置:

  <filter>
    <filter-name>ipCount</filter-name>
    <filter-class>cn.edu.filter.IpCountFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>ipCount</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  


3是show.jsp中列印結果

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>統計網站訪問量</title>
</head>
<body>
<h1 align="center">分IP統計訪問次數</h1>
<table align="center" width="60%" border="1">
	<tr>
		<th>IP地址</th>
		<th>訪 問 量</th>
	</tr>
	<!--迴圈遍歷在ServletContext中的map,其中key是ip地址,value是訪問次數 -->
	<c:forEach items="${applicationScope.map }" var="entry">
		<tr>
			<td>${entry.key }</td>
			<td>${entry.value }</td>
		</tr>
	</c:forEach>
</table>
</body>
</html>


那個0:0:0:0....是localhost訪問的,127.0.0.1是127.0.0.1訪問的,不一樣的ip