1. 程式人生 > >Servlet監聽器(統計線上人數案例)

Servlet監聽器(統計線上人數案例)

1、監聽器

    (1)什麼是監聽器

        servlet規範當中定義的一種特殊的元件,用來監聽servlet容器產生的事件並進行相應的處理。
        事件主要有兩大類:
        1)生命週期相關的事件:
        當容器建立或者銷燬了request,session,servletContext(servlet上下文)時產生的事件。
        2)綁訂相關的事件:
        當容器呼叫了request,session,servlet上下文的setAttribute,removeAttribute方法時產生的事件。
    (2)如何寫一個監聽器
        step1,寫一個java類,實現相應的監聽器介面。(依據事件型別選擇相應的介面,比如監聽session的建立或者銷燬,使用HttpSessionListener介面)
        step2,在監聽器介面方法裡面,編寫相應的處理邏輯。
        step3,註冊(在web.xml檔案裡面,配置監聽器)。
    (3)servlet上下文
        1)什麼是servlet上下文?
            容器一啟動,會為每一個web應用建立唯一的一個符合ServletContext介面要求的物件。該物件就是servlet上下文。
            該物件有兩個特點:
                a,唯一性:一個web應用一個servlet上下文。
                b,一直存在: 只要容器不關閉或者應用沒有被解除安裝,servlet上下文會一直存在。
        2)如何獲得servlet上下文
                可以通過GenericServlet,ServletConfig,FilterConfig,HttpSession提供的getServletContext方法來獲得servlet上下文。
        3)    作用
            a,綁訂資料
            setAttribute(String name,Object obj);
            Object getAttribute(String name);
            removeAttribute(String name);
            注意:
                request,session,servlet上下文都提供了綁訂資料相關的方法,但是有兩個區別:
                區別1:綁訂資料生存的時間不一樣,servlet上下文 > session > request。
                區別2: 資料共享的範圍不一樣。
                request物件綁訂的資料只有同一個請求所涉及的各個元件可以訪問(轉發,過濾器);
                session物件綁訂的資料只有同一個會話所涉及的各個元件可以訪問;
                servlet上下文綁訂的資料是同一個應用所有的元件都可以訪問。
            儘量優先使用生命週期短的,比如能用request解決,就不要用session。
            b,訪問全域性的初始化引數(同一個應用內部的所有的servlet/filter都可以訪問的初始化引數)。
                step1,使用
                <context-param>
                    <param-name>company</param-name>
                    <param-value>name</param-value>
                </context-param>
                step2,使用
                String ServletContext.getInitParameter( "company");
            c,獲得實際部署時的物理路徑
                String getRealPath(String path);    

2、案例:統計線上人數

index.jsp:

<%@page pageEncoding="utf-8" 
contentType="text/html;charset=utf-8" %>
<html>
	<head></head>
	<body style="font-size:40px;">
		這是首頁<br/>
		當前系統線上人數是:
		<%=application.getAttribute("count") %>
		<br/>
		<a href="logout">退出</a>
	</body>
</html>
web.xml新增配置:
<listener>
  	<listener-class>web.CountListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>web.LogoutServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/logout</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

LogoutServlet.java:
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LogoutServlet extends HttpServlet {

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		HttpSession session = request.getSession();
		session.invalidate();//銷燬session
	}
}

CountListener.java:
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class CountListener implements HttpSessionListener{
	private int count = 0; // 計數器
	/*
	 * session一建立,容器就會呼叫sessionCreated方法。
	 * HttpSessionEvent:事件物件
	 */
	public void sessionCreated(HttpSessionEvent arg0) {
		System.out.println("session created.");
		count ++;
		HttpSession session = arg0.getSession();
		ServletContext sctx = session.getServletContext();
		//將人數(count)綁訂到servlet上下文
		sctx.setAttribute("count", count);
	}
	
	/*
	 * session銷燬之後,容器會呼叫sessionDestroyed方法。
	 */
	public void sessionDestroyed(HttpSessionEvent arg0) {
		System.out.println("session destroyed.");
		count --;
		HttpSession session = arg0.getSession();
		ServletContext sctx = session.getServletContext();
		//將人數(count)綁訂到servlet上下文
		sctx.setAttribute("count", count);
	}

}