Filter和Listener的应用——分IP统计网站访问次数

一:分析

 统计工作需要在所有资源执行前进行,所以需要放在filter中

 这个拦截器仅仅进行统计工作,不进行拦截,所以请求必须继续传递下去

 用Map<String,integer>来保存数据,一个IP一个键值对,故整个网站只需要一个Map即可

使用ServletContextListener,在服务器启动时完成创建工作

将Map保存到servletContext中

Map需要在Filter中对数据进行累加操作

Map需要在页面中使用,打印Map中的数据

 

二:代码

  1)jsp

    

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title>My JSP 'show.jsp' starting page</title>
</head>

<body>
<h1 align="center">显示结果</h1>
<table align="center" width="60%" border="1">
    <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>
</html>

  2)Listener

package listener; /**
 * Created by YuWenHui on 2017/4/9 0009.
 */

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.LinkedHashMap;
import java.util.Map;

public class IPCountListener implements ServletContextListener{

    public IPCountListener() {
    }
    public void contextInitialized(ServletContextEvent sce) {
//        创建map
        Map<String,Integer> map = new LinkedHashMap<String ,Integer>();
        ServletContext application= sce.getServletContext();
        application.setAttribute("map",map);
    }

    public void contextDestroyed(ServletContextEvent sce) {
    }
}

  3)Filter

package filter;

import javax.servlet.*;
import java.io.IOException;
import java.util.Map;

/**
 * Created by YuWenHui on 2017/4/9 0009.
 */
public class IPCountFilter implements Filter {
    private FilterConfig config=null;
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//        获取map,从FilterConfig中可以直接获取到,故先将FilterConfig对象私有化,再进行赋值(在init中)
        ServletContext application = config.getServletContext();
        Map<String,Integer> map = (Map<String, Integer>) application.getAttribute("map" );
//        获取ip地址
        String ip = req.getRemoteAddr();
//        判断IP是否存在
        if (map.containsKey(ip)){ //判断IP是否在map中
            int num = map.get(ip);
            map.put(ip,num+1);
        }else {
            map.put(ip,1);
        }
//        保存map
        application.setAttribute("map",map);
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
            this.config=config;
    }

}

  4)web.xml

 

<filter>
        <filter-name>IPCountFilter</filter-name>
        <filter-class>filter.IPCountFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>IPCountFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<!-- 配置监听器--> <listener> <listener-class>listener.IPCountListener</listener-class> </listener>
原文地址:https://www.cnblogs.com/yuwenhui/p/6684319.html