Listener監聽器
1.Listener監聽器介紹
- Listener監聽器是JavaWeb三大元件之一。JavaWeb三大元件分別是:Servlet程式,Listener監聽器,Filter過濾器。
- Listener是JavaEE的規範,即介面。
- 監聽器的作用是,監聽某種變化(一般就是物件的建立/銷燬,屬性變化),觸發物件方法完成相應的任務。
- JavaWeb中的監聽器共八個,目前最常用的是ServletContextListener,ServletContextAttributeListener,HttpSessionListener和ServletRequestListener。
2.JavaWeb的監聽器
2.1ServletContextListener監聽器
- 作用:監聽ServletContext建立或者銷燬(當我們web應用啟動時,Tomcat就會建立ServletContext物件),即生命週期監聽
- 應用場景:
- 載入初始化的配置檔案;比如spring的配置檔案
- 任務排程(配合定時器Timer/TimerTask)
- 相關方法:
- void contextInitialized(ServletContextEvent sce):建立ServletContext物件時觸發
- void contextDestroyed(ServletContextEven sce):銷燬ServletContext物件時觸發
應用例項
-
首先建立一個專案,新增web支援,因為listener監聽器是Servlet規範,要使用就要引入Servlet.jar包
-
建立一個普通類,如果該類實現了某個監聽介面,那麼此類就是一個監聽器。該類可以監聽的事件由該類實現的監聽介面決定:
package com.listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; /** * 1.當一個類實現了 ServletContextListener 介面時 * 2.該類就是一個監聽器 * 3.該類可以監聽的事件由該類實現的監聽介面決定 ,比如實現ServletContextListener介面, * 那麼該類就可以監聽ServletContext物件的建立和銷燬,以此類推 * 4.下面的MyServletContextListener就是一個監聽者 * 5.當web應用啟動時,就會產生ServletContextEvent事件,會呼叫監聽器的對應事件處理方法 * 如:contextInitialized(),同時會傳遞 事件物件 * 6.程式設計師可以透過 ServletContextEvent 事件物件,來獲取需要的資訊,然後再進行業務處理 * 7.Tomcat怎麼知道這個監聽器存在呢? 因為我們需要在web.xml檔案中進行配置, * 一旦配置後,tomcat啟動後就會反射例項化該監聽器,放到容器裡面去管理 */ public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); System.out.println("MyServletContextListener監聽到=" + servletContext + "被建立..."); //如果我們獲取到ServletContext物件..可以進行業務處理 } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); System.out.println("MyServletContextListener監聽到=" + servletContext + "被銷燬..."); //比如可以對ServletContext 資料進行處理,或者日誌的管理... System.out.println("進行處理工作..."); } }
-
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置監聽器--> <listener> <listener-class>com.listener.MyServletContextListener</listener-class> </listener> </web-app>
-
配置Tomcat
-
點選啟動tomcat時,我們可以看到監聽器被觸發了:
-
點選停止tomcat時,可以看到監聽器再一次被觸發:
2.2ServletContextAttributeListener監聽器
- 作用:監聽ServletContext屬性的變化
- 相關方法:
- void attributeAdded(ServletContextAttributeEvent event):新增屬性時呼叫
- void attributeReplaced(ServletContextAttributeEvent event):替換屬性時呼叫
- void attributeRemoved(ServletContextAttributeEvent event):移除屬性時呼叫
應用例項
- 建立監聽器:MyServletContextAttributeListener
package com.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("MyServletContextAttributeListener 監聽到新增屬性.." +
servletContextAttributeEvent.getName() + "=" +
servletContextAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("MyServletContextAttributeListener 監聽到刪除屬性.." +
servletContextAttributeEvent.getName() + "=" +
servletContextAttributeEvent.getValue());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("MyServletContextAttributeListener 監聽到修改屬性.." +
servletContextAttributeEvent.getName() + "=" +
servletContextAttributeEvent.getValue());
}
}
- 建立servlet:HiServlet
package com.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class HiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//給ServletContext物件操作屬性
ServletContext servletContext = getServletContext();
//新增屬性
servletContext.setAttribute("name", "傑克");
//修改屬性
servletContext.setAttribute("name", "托馬斯");
//刪除屬性
servletContext.removeAttribute("name");
System.out.println("HiServlet 處理完畢...");
}
}
- web.xml:配置監聽器和servlet
<!--配置監聽器-->
<listener>
<listener-class>com.listener.MyServletContextAttributeListener</listener-class>
</listener>
<!--配置HiServlet-->
<servlet>
<servlet-name>HiServlet</servlet-name>
<servlet-class>com.HiServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HiServlet</servlet-name>
<url-pattern>/hiServlet</url-pattern>
</servlet-mapping>
-
重新發布tomcat,在瀏覽器中訪問servlet,後臺輸出如下:
2.3HttpSessionListener監聽器
- 作用:監聽Session建立或銷燬,即生命週期監聽
- 相關方法:
- void sessionCreated(HttpSessionEvent se):建立session時呼叫
- void sessionDestroyed(HttpSessionEvent se):銷燬session時呼叫
- 使用方法和前面一樣,可以用於監聽使用者上線,離線
應用例項
- 建立監聽器:MyHttpSessionListener
package com.listener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
//當session被建立時,設定一個生命週期10s
session.setMaxInactiveInterval(10);
System.out.println("MyHttpSessionListener 監聽到session建立= " + session.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
System.out.println("MyHttpSessionListener 監聽到session銷燬= " + session.getId());
}
}
- 修改HiServlet程式碼:
package com.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class HiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取session物件
request.getSession();
System.out.println("HiServlet 處理完畢...");
}
}
- 配置監聽器:
<listener>
<listener-class>com.listener.MyHttpSessionListener</listener-class>
</listener>
-
現在我們重啟Tomcat,可以看到還沒有訪問HiServlet,就已經建立了兩個session。這是因為啟動Tomcat時,會預設訪問專案首頁面,tomcat會自動建立兩個session,這裡忽略即可。
-
在瀏覽器訪問HiServlet,可以看到後臺首先建立了一個session,在設定的生命週期內不訪問該session,顯示該session被銷燬。
HttpSessionListener監聽器可以用於監聽使用者上線離線
注意:這裡的session不是瀏覽器一關閉就銷燬,session的銷燬是伺服器端去輪詢決定的,因此如果想要使用者瀏覽器一關閉就銷燬session,可以透過前端在使用者瀏覽器關閉之前,向伺服器傳送一個通知,伺服器收到通知後銷燬該session即可。
2.4HttpSessionAttributeListener監聽器
- 作用:監聽Session屬性的變化
- 相關方法:
- void attributeAdded(ServletRequestAttributeEvent event):新增屬性時呼叫
- void attributeReplaced(ServletRequestAttributeEvent event):替換屬性時呼叫
- void attributeRemoved(ServletRequestAttributeEvent event):移除屬性時呼叫
- 使用少,使用方法和前面一樣。
應用例項
- 建立監聽器:MyHttpSessionAttributeListener
package com.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("MyHttpSessionAttributeListener 監聽到 session新增屬性= "
+ httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("MyHttpSessionAttributeListener 監聽到 session刪除屬性= "
+ httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("MyHttpSessionAttributeListener 監聽到 session修改屬性= "
+ httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue());
}
}
- 修改HiServlet
package com.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class HiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取session物件
HttpSession session = request.getSession();
//新增屬性
session.setAttribute("age", 888);
//修改屬性
session.setAttribute("age", 999);
//刪除屬性
session.removeAttribute("age");
System.out.println("HiServlet 處理完畢...");
}
}
- 配置監聽器
<listener>
<listener-class>com.listener.MyHttpSessionAttributeListener</listener-class>
</listener>
-
redeployTomcat,在瀏覽器訪問hiServlet,後臺輸出如下:
2.5ServletRequestListener監聽器
- 作用:監聽Request建立或者銷燬,即Request物件的生命週期監聽
- 相關方法:
- void requestInitialized(ServletRequestEvent sre):建立request物件時觸發
- void requestDestroyed(ServletRequestEvent sre):銷燬request物件時觸發
- 可以用來監控某個IP訪問我們網站的頻率,做日誌記錄,或者訪問資源的情況等。
應用例項
- 建立監聽器:MyServletRequestListener
package com.listener;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("MyServletRequestListener 監聽到request物件被建立 ");
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
System.out.println("記錄訪問日誌...");
System.out.println("訪問IP= " + servletRequest.getRemoteAddr());
System.out.println("訪問的資源= " + ((HttpServletRequest) servletRequest).getRequestURL());
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("MyServletRequestListener 監聽到request物件被銷燬...");
}
}
-
hiServlet不做修改
-
配置監聽器:
<listener>
<listener-class>com.listener.MyServletRequestListener</listener-class>
</listener>
-
redeployTomcat,在瀏覽器訪問hiServlet,後臺輸出如下:
(中間的session監聽可忽略)
-
訪問專案首頁面,後臺輸出如下:
2.6ServletRequestAttributeListener監聽器
- 作用:監聽Request屬性變化
- 相關方法
- void attributeAdded(ServletRequestAttributeEvent srae):新增屬性時呼叫
- void attributeReplaced(ServletRequestAttributeEvent srae):替換屬性時呼叫
- void attributeRemoved(ServletRequestAttributeEvent srae):移除屬性時呼叫
- 使用方法和前面類似
2.7HttpSessionBindingListener感知監聽器
該監聽器是用來繫結資料的。如果一個物件實現了HttpSessionBindingListener介面,當這個物件被繫結到Session中或者從session中被刪除時,Servlet容器會通知這個物件,而這個物件在接收到通知後,可以做一些初始化或清除狀態的操作。
2.8HttpSessionActivationListener感知監聽器
HttpSessionActivationListener用於監控實現類本身,當實現類物件被新增到session屬性中後,session物件序列化(鈍化)前和反序列化(活化)後都會被執行
相應的方法:
- sessionWillPassivate(HttpSessionEvent se): session鈍化前執行(session從記憶體到硬碟)
- sessionDidActivate(HttpSessionEvent se):session活化後執行(session從硬碟到記憶體)