javaWeb_统计IP

目标 : 使用servlet实现访问某站的IP统计

需要解决的问题 : 1. IP地址用什么存; 2. 存储IP的数据结构何时创建; 3. 何时获取IP存入指定数据结构

设计思路 : 将IP作为键,计数值作为值, 存储在Map集合中. Map集合的创建, 由于Map集合是相对于全站的,而不是会话或者本次request,所以使用ServletContext进行存储.使用ServletContextListener监听器进行监听ServletContext的创建事件, 监听到之后创建Map. 使用/* 过滤器Filter过滤所有对于本站的请求, 得到Map, 对于Servlet3来说ServletRequest可以直接获取ServletContext,对于servlet2来说通过request.getSession().getServletContext(). 如果Map已经存在该IP,获取count值, 自增后放入map中,没有的话直接将count值设置为1.

实际代码 : 

  1. ServletContext事件监听器

 1 package com.theangryz.listener;
 2 
 3 import javax.servlet.Servlet;
 4 import javax.servlet.ServletContext;
 5 import javax.servlet.ServletContextEvent;
 6 import javax.servlet.ServletContextListener;
 7 import java.util.LinkedHashMap;
 8 import java.util.Map;
 9 
10 public class IpListener implements ServletContextListener {
11     @Override
12     public void contextInitialized(ServletContextEvent servletContextEvent) {
13         ServletContext application = servletContextEvent.getServletContext();
14         Map<String, Integer> map = new LinkedHashMap<>();
15         application.setAttribute("map", map);
16     }
17 
18     @Override
19     public void contextDestroyed(ServletContextEvent servletContextEvent) {
20 
21     }
22 }

  2. Filter过滤器

 1 package com.theangryz.filter;
 2 
 3 import javax.servlet.*;
 4 import java.io.IOException;
 5 import java.util.Map;
 6 
 7 public class IpFilter implements Filter {
 8     @Override
 9     public void init(FilterConfig filterConfig) throws ServletException {
10 
11     }
12 
13     @Override
14     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
15         ServletContext application = servletRequest.getServletContext();
16         Map<String, Integer> map = (Map<String, Integer>)application.getAttribute("map");
17         String ip = servletRequest.getRemoteAddr();
18         if (map.containsKey(ip)){
19             int count = map.get(ip);
20             map.put(ip, ++count);
21         }else{
22             map.put(ip, 1);
23         }
24         filterChain.doFilter(servletRequest, servletResponse);
25     }
26 
27     @Override
28     public void destroy() {
29 
30     }
31 }

  3. web.xml WEB容器的配置文件, 用于告诉容器自己定义的Listener, Filter, Servlet

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

  <display-name>Archetype Created Web Application</display-name>


  <filter>
    <filter-name>EncofingFilter</filter-name>
    <filter-class>com.theangryz.filter.EncodingFilter</filter-class>
  </filter>
  <filter>
    <filter-name>IpFilter</filter-name>
    <filter-class>com.theangryz.filter.IpFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>EncofingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>IpFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


  <listener>
    <listener-class>com.theangryz.listener.IpListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>AServlet</servlet-name>
    <servlet-class>com.theangryz.servlet.AServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>BaseServlet</servlet-name>
    <servlet-class>com.theangryz.servlet.BaseServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AServlet</servlet-name>
    <url-pattern>/AServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>BaseServlet</servlet-name>
    <url-pattern>/*Servlet</url-pattern>
  </servlet-mapping>
</web-app>

  4. jsp显示页面

<%--
  Created by IntelliJ IDEA.
  User: idaepad
  Date: 2019/11/28
  Time: 14:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>show page</title>
    <table align="center" border="1" width="60%">
        <tr>
            <td>IP</td>
            <td>IPCount</td>
        </tr>
        <c:forEach items="${applicationScope.map}" var="item">
            <tr>
                <td>${item.key}</td>
                <td>${item.value}</td>
            </tr>
        </c:forEach>
    </table>
</head>
<body>

</body>
</html>

实际编写中遇到的问题

  1. 忘记在web.xml中声明自己定义的Filter, Listener, Servlet

  2. 忘记了如何导入JSTL(jsp标准标签库)

    解决 : <1> : <%@ tablib prefix="c"  url="http://java.sun.com/jsp/jstl/core"  %>

         <2> : pom.xml中引入相关依赖 : 

<dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

   3. 导入了JSPL之后, 使用${entry.key} 与 ${entry.value}(JSP EL : jsp表达式语言), 网页没有显示相关变量值. 显示的还是${entry.value}

    解决 : 原因在于web.xml中的这段代码 : 

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

       在该处的Web applcation 2.3 导致jsp页面不支持JSTL, 所以要使用JSPTL需要在JSP页面进行配置 : <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>

  

猜你喜欢

转载自www.cnblogs.com/gogotao/p/11965288.html