网站计数器

1.概述

     网站计数器对于网站管理者来说是一个非常值得关注的部分,它记录了网站被访问的次数,客观地反映了网站受欢迎的程度。如果网站的点击率很高,访问者也会认为网站值得关注,因而耐心驻足,进而增加网站的访问量,提高网站的知名度。

    本实例中主要应用Servlet中的过滤器技术统计网站的访问量,并且将客户端的IP地址、登录时间和网站的访问次数存储到数据库中;然后在网站的页面中以图形的形式输出网站的访问量,同时还输出网站的最后登录IP和登录时间。

2.技术要点

别致图形计数器设计主要应用Servlet过滤器完成网站访问量数据的统计。应用Servlet过滤器必须实现Filter接口。下面对Filter接口进行详细讲解。

Filter接口

Filter接口存放于javax.servlet包中,是过滤器必须实现的接口。主要包含以下三个方法:

init()方法,在doFilter()方法前被调用,负责设置FilterConfig对象。语法如下:

public void init(FilterConfig filterConfig) throws ServletException 

filterConfig:为过滤器提供初始化参数和访问ServletContext对象。

doFilter()方法,过滤器的主要方法,当客户端请求目标资源时,容器就会调用与这个目标资源相关联的过滤器的doFilter()方法。实现对请求和响应进行处理,执行过滤器的特殊功能。

doFilter()方法的语法如下:

public synchronized void doFilter(ServletRequest request, ServletResponse response,

            FilterChain Chain) throws

            ServletException, IOException

当过滤器的特殊功能完成后,则调用Chain.doFilter(request, response)将请求传给下一个过滤器(或者目标资源),也可以直接向客户端返回响应信息,或者应用RequestDispatcher的forward()和include()方法,以及HttpServletResponse的sendRedirect()方法将请求转向其他资源。

destroy()方法,结束过滤器的生命周期,释放过滤器使用的资源。语法如下:

public void destroy()

3.具体实现

(1)创建db_database01数据库,在数据库中创建tb_counts数据表,用于存储客户的登录时间、客户端的IP地址和网站的访问次数。

(2)编写连接和操作数据库的公共类UserDao。包括加载数据库驱动的方法、连接数据库的方法、查询数据的方法、更新数据库的方法和关闭数据库的方法。其中通过selectStatic()方法实现对数据库的查询操作,关键代码如下:

public ResultSet selectStatic(String sql) throws SQLException {

         ResultSet rs=null;                       //定义ResultSet接口的返回值

        if (con == null) {                        //判断如果数据库没有连接

            Connection();              //则执行该方法,连接数据库

        }

               try {

        stmt = con.createStatement();   //创建返回Statement实例

        rs = stmt.executeQuery(sql);    //执行静态sql语句

         } catch (SQLException e) {

                     e.printStackTrace();

                    }

        return rs;

    }

通过executeUpdate()方法实现更新数据库中数据的操作,关键代码如下:

public boolean executeUpdate(String sql) {

        if (con == null) {                                  //判断如果数据库没有连接

            Connection();                        //则执行该方法,连接数据库

        }

        try {

            stmt = con.createStatement();               //创建返回Statement实例

            int iCount = stmt.executeUpdate(sql);   //执行静态sql语句

            System.out.println("操作成功,所影响的记录数为" + String.valueOf(iCount));

        } catch (SQLException e) {

            System.out.println(e.getMessage());

            return false;

        }

        closeConnection();                         //关闭数据库的操作

        return true;

    }

(3)编写Stat_flux类。创建read_Flux()方法,读取数据库中的数据,并且将读取的数据写入到List集合;创建write_Flux()方法执行更新数据库中数据的操作;创建Stat_count()方法,实现将数据库中的访问量由数字到图形的转换。

read_Flux()方法的关键代码如下:

public List<String> read_Flux() {

        List<String> list = new ArrayList<String>();           //通过ArrayList类实例化List集合

        try {

            String sqls = "select * from tb_counts ";   //定义sql查询语句

            ResultSet rss = conn.selectStatic(sqls);    //调用数据库操作类中的方法执行查询操作

            rss.next();                               //获取查询结果

            String counts = rss.getString("counts");           //获取统计次数

            String last_ip = rss.getString("last_ip");      //获取最后的访问IP

            String last_date = rss.getString("last_date");       //获取最后的访问时间

            String str_pic = Stat_count(counts);        //执行统计数字转换成图形类中的方法,并获取到返回结果

            conn.closeConnection();                   //执行关闭数据库的操作

            list.add(last_ip);                                  //将ip地址添加到List中

            list.add(last_date);                              //将时间添加到List中

            list.add(str_pic);                                 //将图形数据添加到List中

        } catch (SQLException e) {

            e.printStackTrace();

        }

        return list;

    }

Stat_count()方法的关键代码如下:

public String Stat_count(String counts){

            String zeno="";

           int length=counts.length();              //获取字符串的长度

            int i=0;

           while(i<10-length){                 //根据字符串的总长度,计算出补位值0的个数

           zeno+="<img src='images\0.jpg'/>";     //循环输出图形中代表0的图形

                 i++;

           }

      String count="";                           //定义变量,用于输出指定字符代表的图形

        int ii=0;

            while(ii<length){                 //根据字符串的长度进行循环输出

           count+="<img src='images\"+counts.charAt(ii)+".jpg'/>";        //输出字符串中指定字符代表的图形

           ii++;

           }

            String backstr=zeno+count;          //定义字符串变量,合并输出结果

            return backstr;                            //返回输出结果

      }

(4)编写Servlet过滤器类Filter_flux,实现通过过滤器来统计网站的流量。首先创建init()方法,然后创建doFilter()方法,实现输出和更新网站访问量数据的功能,为了更准确的统计出网站的访问量,还通过自定义变量flux和session变量实现了防止页面刷新的功能;最后创建destroy()方法。Filter_flux类的关键代码如下:

public class Filter_flux extends HttpServlet implements Filter {

    private static int flux = 0;

    Stat_Flux stat_flux = new Stat_Flux();

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public synchronized void doFilter(ServletRequest request, ServletResponse response,

            FilterChain Chain) throws

            ServletException, IOException {

        HttpSession session = ((HttpServletRequest) request).getSession();   //初始化session变量

        if (flux == session.getAttribute("flux")) {   //判断当flux的值等于session的值时,直接读取记录

            List<String> list = stat_flux.read_Flux();

            request.setAttribute("count", list.get(2));                 //将获取到数据写入到request请求中

            request.setAttribute("last_ip", list.get(0));                         //将获取到数据写入到request请求中

            request.setAttribute("last_date", list.get(1));                  //将获取到数据写入到request请求中

        } else {

            this.flux++;                                         //flux值增加

            session.setAttribute("flux", flux);                     //将flux的值写入到session中

            String ip = request.getRemoteAddr();                      //获取客户端的IP

            DateTime DateTime = new DateTime();                  //实例化获取日期时间类

            String datetime = DateTime.DateTime();                   //调用日期时间类中方法获取当前时间

            stat_flux.write_Flux(ip, datetime);

            List<String> list = stat_flux.read_Flux();

            request.setAttribute("count", list.get(2));                 //将获取到数据写入到request请求中

            request.setAttribute("last_ip", list.get(0));                         //将获取到数据写入到request请求中

            request.setAttribute("last_date", list.get(1));                  //将获取到数据写入到request请求中

        }

        Chain.doFilter(request, response);

    }

    public void destroy() {

    }

}

最后,在web.xml文件中配置Filter_flux类,首先使用<filter-name>与<filter-class>标签配置filter的名称与所在包的类名,然后再通过<filter-mapping>标签配置filter的映射路径,关键代码如下:

<filter>

      <!-- filter的名称 -->

      <filter-name>Filter_flux</filter-name>

      <!-- filter t的所在包的类名称 -->

      <filter-class>com.pkh.Filter_flux</filter-class>

</filter>

      <filter-mapping>

            <!-- filter的映射名称 -->

            <filter-name>Filter_flux</filter-name>

            <!-- filter 的映射路径 -->

            <url-pattern>/*</url-pattern>

            <!-- filter 的映射使用的类型 -->

            <dispatcher>REQUEST</dispatcher>

            <dispatcher>FORWARD</dispatcher>

         </filter-mapping>

(5)创建index.jsp页,应用getAttribute方法获取网站最后登录的IP地址、登录时间和网站的访问量。

原文地址:https://www.cnblogs.com/zkn11199/p/5581869.html