天天看點

利用Servlet監聽器實作簡單網站通路量和線上人數統計

轉自 http://blog.sina.com.cn/s/blog_621a42970100gblw.html 

Servlet監聽器主要有三種,在ServletContext(上下文對象)、Session(會話)和request(請求)這三對象上進行監聽,可以監聽對象的建立、銷毀、添加屬性、删除屬性、屬性值的改變等。ServletContext對象的作用域在整個WEB應用程式,類似于Static屬性;Session的作用域在一個會話,一個會話可以了解為一個從一個浏覽器送出請求到伺服器開始,一直到浏覽器關閉(但通常我們可以設定會話的生命期,防止那些獲得連接配接後卻長時間沒有再向伺服器送出請求的情況),相當于類的成員變量;request的作用域僅在一次請求,即浏覽器發送一次請求到伺服器處理該請求并發回響應就結束了,相當于局部變量。

    要實作統計網站的曆史通路量就要利用ServletContext的全局屬性的特點了,為了在伺服器停止後,之前的通路量不會消失,我們就應該在伺服器關閉前将目前的通路量存放到檔案裡面,以便下一次重新開機伺服器後,可以繼續使用。在ServletContext上面建立監聽器,監聽上下文對象的銷毀和建立,并同時在建立上下文的時候從檔案讀取曆史資料,在上下文銷毀的時候将目前通路量寫入到檔案儲存起來。以後每當建立一個會話(Session)的時候,就将目前的計數值加一。線上人數的統計是利用在建立會話的時候,将線上人數之加一,在會話對象銷毀的時候,将線上人數值減一。因為兩種人數統計都是被所有使用者共享的資訊,是以使用ServletContext的setAttribute()和getAttribut()方法來對總人數和線上人數進行管理。

    建立對上下文對象的監聽器:

public class ContextListener implements ServletContextListener{

 public void contextDestroyed(ServletContextEvent arg0) {

  // TODO Auto-generated method stub

  Properties pro = new Properties();  

  try {

   pro.setProperty("counter", arg0.getServletContext().getAttribute("counter").toString());

   String filePath = arg0.getServletContext().getRealPath("/WEB-INF/classes/db/count.txt");

//上下文對象銷毀時,将目前通路量寫入檔案

   OutputStream os = new FileOutputStream(filePath);

   pro.store(os, null);

  } catch (IOException e) {

   // TODO Auto-generated catch block

   e.printStackTrace();

  }

 }

 public void contextInitialized(ServletContextEvent arg0) {

  // TODO Auto-generated method stub

  arg0.getServletContext().setAttribute("online", 0);

  Properties pro = new Properties();

  InputStream in = ContextListener.class.getResourceAsStream("/db/count.txt");

  String n = null;

  try {

   pro.load(in);

   n = pro.getProperty("counter");//從計數檔案中讀取該站的曆史通路量

   arg0.getServletContext().setAttribute("counter", Integer.parseInt(pro.getProperty("counter")));

  } catch (IOException e) {

   // TODO Auto-generated catch block

   System.out.println("讀取計數檔案失敗");

  }

  System.out.println("建立上下文對象" + n);

 }

}

 建立對會話對象的監聽:

public class SessionListener implements HttpSessionListener{

 public void sessionCreated(HttpSessionEvent arg0) {

  // TODO Auto-generated method stub

   HttpSession session = arg0.getSession();

  int i = (Integer)session.getServletContext().getAttribute("online");//獲得目前線上人數,并将其加一

  session.getServletContext().setAttribute("online", i+1);

  int n = (Integer)session.getServletContext().getAttribute("counter");//建立一個會話就将通路量加一

  session.getServletContext().setAttribute("counter", n+1);

  Properties pro = new Properties();  

  try {//通路人數加一後就将結果寫入檔案(防止不正常關閉伺服器)

   pro.setProperty("counter", session.getServletContext().getAttribute("counter").toString());

   String filePath = session.getServletContext().getRealPath("/WEB-INF/classes/db/count.txt");

   OutputStream os = new FileOutputStream(filePath);

   pro.store(os, null);

  } catch (IOException e) {

   // TODO Auto-generated catch block

   System.out.println("寫入計數檔案失敗");

  }

  System.out.println("建立一個會話");

 }

 public void sessionDestroyed(HttpSessionEvent arg0) {

  // TODO Auto-generated method stub

  //銷毀會話的時候,需要将線上人數減一

  ServletContext context = arg0.getSession().getServletContext();

  Integer i = (Integer)context.getAttribute("online");

  context.setAttribute("online", i-1);

  arg0.getSession().invalidate();

  System.out.println("銷毀一個會話");

 }

   在web.xml檔案中将監聽器注冊,在建立和銷毀對象時就會觸發該事件了。 因為我們通常做測試的時候,伺服器的關閉是沒有通過正常的方式來進行的,是以程式中在建立一個會的時候将網站曆史通路資料值加一後就将該值在檔案中進行更新,否則可能該值不會改變。建立一個會話是通過request.getSession()來觸發的,是以在做測試的Servlet中需要加上HttpSession session = request.getSession();

  //設定會話的最大不活動時間為60秒

  session.setMaxInactiveInterval(60);。

上面的隻是一個簡單的模拟程式,存在許多缺陷。

繼續閱讀