利用Servlet监听器实现简单网站访问量和在线人数统计
轉(zhuǎn)自 http://blog.sina.com.cn/s/blog_621a42970100gblw.html?
Servlet監(jiān)聽器主要有三種,在ServletContext(上下文對象)、Session(會話)和request(請求)這三對象上進行監(jiān)聽,可以監(jiān)聽對象的創(chuàng)建、銷毀、添加屬性、刪除屬性、屬性值的改變等。ServletContext對象的作用域在整個WEB應(yīng)用程序,類似于Static屬性;Session的作用域在一個會話,一個會話可以理解為一個從一個瀏覽器發(fā)出請求到服務(wù)器開始,一直到瀏覽器關(guān)閉(但通常我們可以設(shè)置會話的生命期,防止那些獲得連接后卻長時間沒有再向服務(wù)器發(fā)出請求的情況),相當于類的成員變量;request的作用域僅在一次請求,即瀏覽器發(fā)送一次請求到服務(wù)器處理該請求并發(fā)回響應(yīng)就結(jié)束了,相當于局部變量。
????要實現(xiàn)統(tǒng)計網(wǎng)站的歷史訪問量就要利用ServletContext的全局屬性的特點了,為了在服務(wù)器停止后,之前的訪問量不會消失,我們就應(yīng)該在服務(wù)器關(guān)閉前將當前的訪問量存放到文件里面,以便下一次重啟服務(wù)器后,可以繼續(xù)使用。在ServletContext上面創(chuàng)建監(jiān)聽器,監(jiān)聽上下文對象的銷毀和創(chuàng)建,并同時在創(chuàng)建上下文的時候從文件讀取歷史數(shù)據(jù),在上下文銷毀的時候?qū)斍霸L問量寫入到文件保存起來。以后每當創(chuàng)建一個會話(Session)的時候,就將當前的計數(shù)值加一。在線人數(shù)的統(tǒng)計是利用在創(chuàng)建會話的時候,將在線人數(shù)之加一,在會話對象銷毀的時候,將在線人數(shù)值減一。因為兩種人數(shù)統(tǒng)計都是被所有用戶共享的信息,所以使用ServletContext的setAttribute()和getAttribut()方法來對總?cè)藬?shù)和在線人數(shù)進行管理。
????創(chuàng)建對上下文對象的監(jiān)聽器:
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");//從計數(shù)文件中讀取該站的歷史訪問量
???arg0.getServletContext().setAttribute("counter", Integer.parseInt(pro.getProperty("counter")));
??} catch (IOException e) {
???// TODO Auto-generated catch block
???System.out.println("讀取計數(shù)文件失敗");
??}
??System.out.println("創(chuàng)建上下文對象" + n);
?}
}
?創(chuàng)建對會話對象的監(jiā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");//獲得當前在線人數(shù),并將其加一
??session.getServletContext().setAttribute("online", i+1);
??int n = (Integer)session.getServletContext().getAttribute("counter");//創(chuàng)建一個會話就將訪問量加一
??session.getServletContext().setAttribute("counter", n+1);
??Properties pro = new Properties();??
??try {//訪問人數(shù)加一后就將結(jié)果寫入文件(防止不正常關(guān)閉服務(wù)器)
???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("寫入計數(shù)文件失敗");
??}
??System.out.println("創(chuàng)建一個會話");
?}
?public void sessionDestroyed(HttpSessionEvent arg0) {
??// TODO Auto-generated method stub
??//銷毀會話的時候,需要將在線人數(shù)減一
??ServletContext context = arg0.getSession().getServletContext();
??Integer i = (Integer)context.getAttribute("online");
??context.setAttribute("online", i-1);
??arg0.getSession().invalidate();
??System.out.println("銷毀一個會話");
?}
}?
???在web.xml文件中將監(jiān)聽器注冊,在創(chuàng)建和銷毀對象時就會觸發(fā)該事件了。?因為我們通常做測試的時候,服務(wù)器的關(guān)閉是沒有通過正常的方式來進行的,所以程序中在創(chuàng)建一個會的時候?qū)⒕W(wǎng)站歷史訪問數(shù)據(jù)值加一后就將該值在文件中進行更新,否則可能該值不會改變。創(chuàng)建一個會話是通過request.getSession()來觸發(fā)的,所以在做測試的Servlet中需要加上HttpSession session = request.getSession();
??//設(shè)置會話的最大不活動時間為60秒
??session.setMaxInactiveInterval(60);。
上面的只是一個簡單的模擬程序,存在許多缺陷。
總結(jié)
以上是生活随笔為你收集整理的利用Servlet监听器实现简单网站访问量和在线人数统计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 密钥生成器KeyPairGenerato
- 下一篇: 一次索引搞定的调优例子