ip | count |
192.168.1.111 | 2 |
192.168.1.112 | 59 |
因为一个网站可能有多个页面,无论哪个页面被访问,都要统计访问次数,统计工作需要在所有资源之前都执行,所以使用过滤器最为方便。
因为需要分IP统计,所以可以在过滤器中创建一个Map,使用IP为key,访问次数为value。当有用户访问时,获取请求的IP,如果IP在Map中存在,
说明以前访问过,那么在访问次数上加1,即可;IP在Map中不存在,那么设置次数为1。
把这个Map放在ServletContextListener,在服务器启动时完成创建(使用监听器),并只在到ServletContext中)。
Ø Map需要在Filter中用来保存数据
Ø Map需要在页面使用,打印Map中的数据
代码
index.jsp
<body> <h1>分IP统计访问次数</h1> <table align="center" width="50%" border="1"> <tr> <th>IP地址</th> <th>次数</th> </tr> <c:forEach items="${applicationScope.ipCountMap }" var="entry"> <tr> <td>${entry.key }</td> <td>${entry.value }</td> </tr> </c:forEach> </table> </body> |
IPFilter
publicclass IPFilter implements Filter { private ServletContext context;
publicvoid init(FilterConfig fConfig) throws ServletException { context = fConfig.getServletContext(); Map<String, Integer> ipCountMap = Collections .synchronizedMap(new LinkedHashMap<String, Integer>()); context.setAttribute("ipCountMap", ipCountMap); }
@SuppressWarnings("unchecked") publicvoid doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String ip = req.getRemoteAddr();
Map<String, Integer> ipCountMap = (Map<String, Integer>) context .getAttribute("ipCountMap"); Integer count = ipCountMap.get(ip); if (count == null) { count = 1; } else { count += 1; } ipCountMap.put(ip, count);
context.setAttribute("ipCountMap", ipCountMap); chain.doFilter(request, response); }
publicvoid destroy() {} } |
<filter> <display-name>IPFilter</display-name> <filter-name>IPFilter</filter-name> <filter-class>cn.itcast.filter.ip.IPFilter</filter-class> </filter> <filter-mapping> <filter-name>IPFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |