一、簡介
servlet事件監聽器可以對web應用程式執行生命週期中發生的事件進行監聽,主要事件是ServletContext、HttpSession、ServletRequest物件的建立和銷燬,這裡將結合原始碼進行解析。
二、ServletContextListener
ServletContextListener用於監聽ServletContext的建立和銷燬(容器的初始化和銷燬),
2.1 原始碼
ServletContext監聽器的核心類是ServletContextListener,關聯還類有ServletContextEvent、EventObject,相關原始碼定義如下:
package java.util;
//所有事件的父類
public class EventObject implements java.io.Serializable {
//事件源(事件發生的物件)
protected transient Object source;
//建構函式
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
//獲取事件源(事件發生的物件)
public Object getSource() {
return source;
}
//toString方法
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
package javax.servlet;
//用於通知的事件類
public class ServletContextEvent extends java.util.EventObject {
//構造器
public ServletContextEvent(ServletContext source) {
super(source);
}
//獲取關聯的ServletContext
public ServletContext getServletContext () {
return (ServletContext) super.getSource();
}
}
package java.util;
//所有監聽器必須實現的標記介面(空實現)
public interface EventListener {
}
package javax.servlet;
import java.util.EventListener;
//ServletContext生命週期的事件監聽器
public interface ServletContextListener extends EventListener {
//容器初始化時,ServletContext物件建立後呼叫(在所有filter和servlet初始化前)
public void contextInitialized(ServletContextEvent sce);
//ServletContext物件銷燬時呼叫(在所有servlet和filter銷燬前)
public void contextDestroyed(ServletContextEvent sce);
}
2.2 示例
2.2.1 定義監聽類
package listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
//也可使用註解註冊監聽器
public class DemoServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//獲取ServletContext物件
ServletContext ctx = sce.getServletContext();
//獲取context初始化引數
String configLocation = ctx.getInitParameter("configLocation");
//獲取事件源(即監聽的物件或者發生事件的物件),這裡是ServletContext物件
Object srcObj = sce.getSource();
System.out.println("invoke contextInitialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("invoke contextDestroyed");
}
}
2.2.2 監聽器註冊
監聽器註冊可以採用xml註冊或註解註冊,這裡以xml註冊為例,在web.xml新增程式碼:
<context-param>
<param-name>configLocation</param-name>
<param-value>classpath:web_config.xml</param-value>
</context-param>
<listener>
<listener-class>listener.DemoServletContextListener</listener-class>
</listener>
三、HttpSessionListener
Session監聽器用於監聽HttpSession的建立和銷燬事件。
3.1 原始碼
session監聽的主要類是HttpSessionListener,關聯類同前一樣有HttpSessionEvent,原始碼如下:
package javax.servlet.http;
//session事件
public class HttpSessionEvent extends java.util.EventObject {
//構造器
public HttpSessionEvent(HttpSession source) {
super(source);
}
//獲取事件源
public HttpSession getSession () {
return (HttpSession) super.getSource();
}
}
package javax.servlet.http;
import java.util.EventListener;
//監聽HttpSession生命週期的事件,註冊可以透過WebListener註解或ServletContext.addListener方法註冊
public interface HttpSessionListener extends EventListener {
//接收session建立通知
public void sessionCreated(HttpSessionEvent se);
//接收事件銷燬通知
public void sessionDestroyed(HttpSessionEvent se);
}
3.2 示例
3.2.1 定義session監聽器
這裡直接使用@WebListener註解註冊監聽器。
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class DemoHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
//獲取session
HttpSession session = se.getSession();
//獲取sessionId
String sessionId = session.getId();
System.out.println("invoke sessionCreated, sessionId: "+sessionId);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("invoke sessionDestroyed");
}
}
3.2.2 定義建立session的servlet
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(name = "DemoSessionEventServlet", urlPatterns = "/demoSessionEventServlet")
public class DemoSessionEventServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
resp.getWriter().write("this is HttpSessionListener test, sessionId: "+session.getId());
}
}
四、ServletRequestListener
請求監聽器用於監聽請求進入和離開容器時事件。
4.1 原始碼
請求監聽的主要類是ServletRequestListener,關聯類同前一樣有ServletRequestEvent,原始碼如下:
package javax.servlet;
//ServletRequest生命週期中的事件
public class ServletRequestEvent extends java.util.EventObject {
//請求
private final transient ServletRequest request;
//構造器,引數為ServletContext(作為事件源)和ServletRequest
public ServletRequestEvent(ServletContext sc, ServletRequest request) {
super(sc);
this.request = request;
}
//獲取請求ServletRequest
public ServletRequest getServletRequest () {
return this.request;
}
//獲取ServletContext
public ServletContext getServletContext () {
return (ServletContext) super.getSource();
}
}
package javax.servlet;
import java.util.EventListener;
//請求進入和離開web容器時的事件通知(相應方法呼叫),註冊方式可以透過@WebListener註解或ServletContext.addListener方法
public interface ServletRequestListener extends EventListener {
//ServletRequest物件銷燬時呼叫(請求離開容器的最後一個servlet或第一個filter時呼叫)
public void requestDestroyed(ServletRequestEvent sre);
//ServletRequest物件建立時呼叫(請求進入容器的第一個servlet或filter時呼叫)
public void requestInitialized(ServletRequestEvent sre);
}
4.2 示例
4.2.1 定義請求監聽器
package listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class DemoServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("invoke requestDestroyed");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
ServletContext ctx = sre.getServletContext();
ServletRequest req = sre.getServletRequest();
System.out.println("invoke requestInitialized");
}
}
4.2.2 定義請求servlet
package listener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "demoRequestServlet", urlPatterns = "/demoRequestServlet")
public class DemoRequestServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("this is a demo servlet");
System.out.println("do service");
}
}
結果:
請求:
console輸出:
invoke requestInitialized
do service
invoke requestDestroyed
五、備註
更多監聽器知識,請檢視相關原始碼。