天天看點

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" target="_blank" rel="external nofollow" >退出</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);
	}

}
           

繼續閱讀