Servlet監聽器(統計線上人數案例)
阿新 • • 發佈:2019-01-11
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:
web.xml新增配置:<%@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>
<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);
}
}