JavaWeb三大組件之監(jiān)聽(tīng)器Listener詳解
監(jiān)聽(tīng)器Listener
概念分析 :
在JavaWeb應(yīng)用程序中,Listener(監(jiān)聽(tīng)器)是一種機(jī)制,用于監(jiān)聽(tīng)和響應(yīng)特定的事件。它可以感知并響應(yīng)與應(yīng)用程序相關(guān)的事件,從而執(zhí)行相應(yīng)的邏輯處理。
事件是在應(yīng)用程序運(yùn)行過(guò)程中發(fā)生的特定動(dòng)作或狀態(tài)改變。例如,Web應(yīng)用程序的啟動(dòng)和關(guān)閉、請(qǐng)求的到達(dá)和完成、會(huì)話(huà)的創(chuàng)建和銷(xiāo)毀等都被認(rèn)為是事件。監(jiān)聽(tīng)器會(huì)注冊(cè)對(duì)這些事件的感興趣,并在事件發(fā)生時(shí)調(diào)用相應(yīng)的回調(diào)方法來(lái)執(zhí)行預(yù)定的業(yè)務(wù)邏輯。
監(jiān)聽(tīng)器的概念可以類(lèi)比于現(xiàn)實(shí)生活中的觀察者模式。在觀察者模式中,一個(gè)對(duì)象(觀察者)注冊(cè)對(duì)另一個(gè)對(duì)象(被觀察者)的事件感興趣,并在被觀察者觸發(fā)相應(yīng)事件時(shí)得到通知并執(zhí)行相應(yīng)操作。類(lèi)似地,在JavaWeb應(yīng)用程序中,監(jiān)聽(tīng)器充當(dāng)觀察者的角色,可以監(jiān)聽(tīng)和響應(yīng)特定的事件。
通過(guò)使用監(jiān)聽(tīng)器,開(kāi)發(fā)者可以將應(yīng)用程序的關(guān)鍵行為和狀態(tài)抽象成事件,并在需要的時(shí)候采取相應(yīng)的措施。比如,在Web應(yīng)用程序啟動(dòng)時(shí),可以使用ServletContextListener來(lái)進(jìn)行初始化操作;在每次請(qǐng)求到達(dá)時(shí),可以使用ServletRequestListener來(lái)獲取請(qǐng)求信息等。
監(jiān)聽(tīng)器的設(shè)計(jì)使得應(yīng)用程序更加靈活和可擴(kuò)展。它提供了一種松耦合的方式來(lái)解耦應(yīng)用程序的不同模塊,并實(shí)現(xiàn)事件驅(qū)動(dòng)的編程模型。監(jiān)聽(tīng)器是實(shí)現(xiàn)Web應(yīng)用程序的事件處理和擴(kuò)展性的重要組成部分。
價(jià)值所在 :
監(jiān)聽(tīng)器(Listener)在JavaWeb應(yīng)用程序中具有重要的意義和價(jià)值,主要體現(xiàn)在以下幾個(gè)方面:
- 實(shí)現(xiàn)事件驅(qū)動(dòng)編程:監(jiān)聽(tīng)器的核心概念是基于事件的觸發(fā)和響應(yīng),它使得開(kāi)發(fā)者可以將應(yīng)用程序的關(guān)鍵行為和狀態(tài)抽象成事件,并在事件發(fā)生時(shí)執(zhí)行相應(yīng)的邏輯處理。通過(guò)監(jiān)聽(tīng)器,開(kāi)發(fā)者可以實(shí)現(xiàn)事件驅(qū)動(dòng)編程的思想,更加靈活地響應(yīng)應(yīng)用程序中的各種事件。
- 解耦和模塊化:監(jiān)聽(tīng)器解耦了應(yīng)用程序中不同模塊之間的依賴(lài)關(guān)系。它提供了一種松耦合的方式來(lái)將事件和事件處理的邏輯相互分離,使得不同的模塊可以獨(dú)立地進(jìn)行開(kāi)發(fā)和維護(hù)。通過(guò)監(jiān)聽(tīng)器,開(kāi)發(fā)者可以將特定事件的處理邏輯集中到監(jiān)聽(tīng)器中,從而提高代碼的可讀性和可維護(hù)性。
- 增強(qiáng)可擴(kuò)展性:使用監(jiān)聽(tīng)器可以有效地增強(qiáng)應(yīng)用程序的可擴(kuò)展性。當(dāng)應(yīng)用程序需要添加新的功能或處理新的事件時(shí),可以通過(guò)編寫(xiě)自定義的監(jiān)聽(tīng)器來(lái)實(shí)現(xiàn)。通過(guò)監(jiān)聽(tīng)器,可以在不修改已有代碼的情況下,將新的功能集成到應(yīng)用程序中,從而實(shí)現(xiàn)應(yīng)用程序的動(dòng)態(tài)擴(kuò)展。
- 提供通用的解決方案:一些監(jiān)聽(tīng)器是Web容器預(yù)先定義的,如ServletContextListener、ServletRequestListener和HttpSessionListener等。這些監(jiān)聽(tīng)器提供了一些通用的解決方案,可用于應(yīng)用程序中常見(jiàn)的場(chǎng)景,如應(yīng)用程序的初始化、請(qǐng)求的處理、會(huì)話(huà)管理等。通過(guò)使用這些通用的監(jiān)聽(tīng)器,開(kāi)發(fā)者可以以更加快速和方便的方式完成常見(jiàn)功能的實(shí)現(xiàn)。
所以它提供了一種事件驅(qū)動(dòng)的編程模型,幫助開(kāi)發(fā)者實(shí)現(xiàn)模塊間的解耦和功能的擴(kuò)展,以及提供通用的解決方案。監(jiān)聽(tīng)器在開(kāi)發(fā)Web應(yīng)用程序時(shí)是一種強(qiáng)大的工具,可以提升代碼的可維護(hù)性、可擴(kuò)展性和可讀性。
一. Listener監(jiān)聽(tīng)器的介紹
1. Listener 監(jiān)聽(tīng)器它是 JavaWeb 的三大組件之一。 JavaWeb 的三大組件分別是: Servlet 程 序、 Listener 監(jiān)聽(tīng)器、 Filter 過(guò)濾器
2. Listener 是 JavaEE 的規(guī)范,就是接口
3. 監(jiān)聽(tīng) 器的作用是,監(jiān)聽(tīng)某種變化 ( 一般就是對(duì)象創(chuàng)建 / 銷(xiāo)毀 , 屬性變化 ), 觸發(fā)對(duì)應(yīng)方法完成 相應(yīng)的任務(wù)
4. JavaWeb 中的監(jiān)聽(tīng)器(共八個(gè)) , 目前最常用的是 ServletContextListener
二. Listener的生命周期
監(jiān)聽(tīng)器(Listener)在JavaWeb應(yīng)用程序中起到監(jiān)聽(tīng)和處理事件的作用。監(jiān)聽(tīng)器的生命周期與Web應(yīng)用程序的生命周期密切相關(guān)。
- ServletContextListener:ServletContextListener會(huì)在Web應(yīng)用程序啟動(dòng)時(shí)起作用,并在Web應(yīng)用程序關(guān)閉時(shí)銷(xiāo)毀。具體來(lái)說(shuō),當(dāng)Web容器啟動(dòng)時(shí)會(huì)觸發(fā)contextInitialized()方法,開(kāi)發(fā)者可以在這個(gè)方法中進(jìn)行一些初始化操作;當(dāng)Web容器關(guān)閉時(shí)會(huì)觸發(fā)contextDestroyed()方法,開(kāi)發(fā)者可以在這個(gè)方法中進(jìn)行一些資源釋放、清理操作。
- ServletRequestListener:ServletRequestListener會(huì)在每次客戶(hù)端請(qǐng)求到達(dá)服務(wù)器時(shí)起作用,并在服務(wù)器響應(yīng)完成后銷(xiāo)毀。具體來(lái)說(shuō),當(dāng)客戶(hù)端發(fā)送請(qǐng)求到達(dá)服務(wù)器時(shí)會(huì)觸發(fā)requestInitialized()方法,開(kāi)發(fā)者可以在這個(gè)方法中獲取和處理請(qǐng)求相關(guān)的信息;當(dāng)服務(wù)器響應(yīng)完成后會(huì)觸發(fā)requestDestroyed()方法,開(kāi)發(fā)者可以在這個(gè)方法中進(jìn)行一些善后操作。
- HttpSessionListener:HttpSessionListener會(huì)在每次HttpSession創(chuàng)建和銷(xiāo)毀時(shí)起作用。具體來(lái)說(shuō),當(dāng)用戶(hù)訪(fǎng)問(wèn)Web應(yīng)用程序時(shí),如果尚未創(chuàng)建HttpSession,會(huì)觸發(fā)sessionCreated()方法,在這個(gè)方法中可以進(jìn)行一些會(huì)話(huà)管理的操作;當(dāng)HttpSession被銷(xiāo)毀時(shí),會(huì)觸發(fā)sessionDestroyed()方法,在這個(gè)方法中可以進(jìn)行一些會(huì)話(huà)清理的操作。
注意,監(jiān)聽(tīng)器是通過(guò)在web.xml配置文件中聲明來(lái)啟用的。開(kāi)發(fā)者需要在web.xml文件中添加相應(yīng)的監(jiān)聽(tīng)器聲明,告訴Web容器要監(jiān)聽(tīng)哪些事件,并指定相應(yīng)的監(jiān)聽(tīng)器類(lèi)。
總之,監(jiān)聽(tīng)器的起作用和銷(xiāo)毀是在Web應(yīng)用程序的生命周期中發(fā)生的,監(jiān)聽(tīng)器會(huì)在特定的事件發(fā)生時(shí)被觸發(fā),并執(zhí)行相應(yīng)的回調(diào)方法來(lái)處理事件。
三. 常見(jiàn)的監(jiān)聽(tīng)器
Listener(監(jiān)聽(tīng)器)可以監(jiān)聽(tīng)不同的事件,具體監(jiān)聽(tīng)的事件類(lèi)型取決于監(jiān)聽(tīng)器的種類(lèi)。
在JavaWeb中,常見(jiàn)的監(jiān)聽(tīng)器都是用于監(jiān)聽(tīng)Servlet、JSP和Web應(yīng)用程序中的事件。
下面是一些常見(jiàn)的監(jiān)聽(tīng)器及其監(jiān)聽(tīng)的事件類(lèi)型:
- ServletContextListener:監(jiān)聽(tīng)ServletContext對(duì)象的創(chuàng)建和銷(xiāo)毀事件,當(dāng)Web應(yīng)用程序啟動(dòng)和關(guān)閉時(shí)觸發(fā)。
- ServletRequestListener:監(jiān)聽(tīng)ServletRequest對(duì)象的創(chuàng)建和銷(xiāo)毀事件,在每次客戶(hù)端請(qǐng)求到達(dá)服務(wù)器時(shí)觸發(fā)。
- HttpSessionListener:監(jiān)聽(tīng)HttpSession對(duì)象的創(chuàng)建和銷(xiāo)毀事件,當(dāng)用戶(hù)與Web應(yīng)用程序建立和關(guān)閉會(huì)話(huà)時(shí)觸發(fā)。
- ServletContextAttributeListener:監(jiān)聽(tīng)ServletContext中屬性的添加、修改和刪除事件。
- ServletRequestAttributeListener:監(jiān)聽(tīng)ServletRequest中屬性的添加、修改和刪除事件。
- HttpSessionAttributeListener:監(jiān)聽(tīng)HttpSession中屬性的添加、修改和刪除事件。
- HttpSessionActivationListener:監(jiān)聽(tīng)HttpSession對(duì)象的鈍化(passivation)和活化(activation)事件,與分布式會(huì)話(huà)(Distributed Session)有關(guān)。
- ServletRequestListener:監(jiān)聽(tīng)ServletContext對(duì)象的創(chuàng)建和銷(xiāo)毀事件,以及請(qǐng)求的開(kāi)始和完成。
- ServletContextListener:監(jiān)聽(tīng)ServletContext對(duì)象的創(chuàng)建和銷(xiāo)毀事件,與Web應(yīng)用程序的啟動(dòng)和關(guān)閉有關(guān)。
這只是一部分常見(jiàn)的監(jiān)聽(tīng)器和事件類(lèi)型,根據(jù)具體需求,你也可以自定義監(jiān)聽(tīng)器來(lái)監(jiān)聽(tīng)其他類(lèi)型的事件。
監(jiān)聽(tīng)器提供了一種機(jī)制,讓開(kāi)發(fā)者可以在事件發(fā)生時(shí)執(zhí)行自定義的邏輯操作,以實(shí)現(xiàn)對(duì)特定事件的監(jiān)控和響應(yīng)。
四. 舉例
ServletContextListener
簡(jiǎn)單的ServletContextListener示例,演示在應(yīng)用程序啟動(dòng)和關(guān)閉時(shí)執(zhí)行初始化和清理操作:
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // 應(yīng)用程序啟動(dòng)時(shí)執(zhí)行的初始化操作 System.out.println("應(yīng)用程序已啟動(dòng)"); // 加載配置文件、初始化數(shù)據(jù)庫(kù)連接池等 // ... } @Override public void contextDestroyed(ServletContextEvent sce) { // 應(yīng)用程序關(guān)閉時(shí)執(zhí)行的清理操作 System.out.println("應(yīng)用程序即將關(guān)閉"); // 關(guān)閉數(shù)據(jù)庫(kù)連接池、釋放資源等 // ... } }
在上面的例子中,MyServletContextListener實(shí)現(xiàn)了ServletContextListener接口,并重寫(xiě)了contextInitialized和contextDestroyed方法。
在contextInitialized方法中,你可以執(zhí)行應(yīng)用程序啟動(dòng)時(shí)的初始化操作,比如加載配置文件、初始化數(shù)據(jù)庫(kù)連接池等。
而在contextDestroyed方法中,你可以執(zhí)行應(yīng)用程序關(guān)閉時(shí)的清理操作,比如關(guān)閉數(shù)據(jù)庫(kù)連接池、釋放資源等。
當(dāng)應(yīng)用程序啟動(dòng)時(shí),容器將自動(dòng)調(diào)用contextInitialized方法來(lái)初始化你的應(yīng)用程序。當(dāng)應(yīng)用程序關(guān)閉時(shí),容器將自動(dòng)調(diào)用contextDestroyed方法來(lái)執(zhí)行清理操作。
為了讓監(jiān)聽(tīng)器生效,你還需要在web.xml或使用注解的方式配置監(jiān)聽(tīng)器的部署描述符,具體的配置方式取決于你使用的Servlet容器。例如,在web.xml中添加以下配置:
<listener> <listener-class>com.example.MyServletContextListener</listener-class> </listener>
這樣,當(dāng)應(yīng)用程序啟動(dòng)或關(guān)閉時(shí),MyServletContextListener中的邏輯將被觸發(fā)執(zhí)行。
ServletContextAttributeListener
一個(gè)簡(jiǎn)單的ServletContextAttributeListener示例,展示了當(dāng)ServletContext屬性發(fā)生變化時(shí)執(zhí)行的操作:
import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import javax.servlet.annotation.WebListener; @WebListener public class MyServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent event) { // 當(dāng)ServletContext屬性被添加時(shí)執(zhí)行的操作 String attributeName = event.getName(); Object attributeValue = event.getValue(); System.out.println("ServletContext屬性 " + attributeName + " 添加,值為: " + attributeValue); // 其他處理邏輯 // ... } @Override public void attributeRemoved(ServletContextAttributeEvent event) { // 當(dāng)ServletContext屬性被移除時(shí)執(zhí)行的操作 String attributeName = event.getName(); Object attributeValue = event.getValue(); System.out.println("ServletContext屬性 " + attributeName + " 被移除,值為: " + attributeValue); // 其他處理邏輯 // ... } @Override public void attributeReplaced(ServletContextAttributeEvent event) { // 當(dāng)ServletContext屬性被替換時(shí)執(zhí)行的操作 String attributeName = event.getName(); Object oldAttributeValue = event.getValue(); Object newAttributeValue = event.getServletContext().getAttribute(attributeName); System.out.println("ServletContext屬性 " + attributeName + " 被替換,舊值為: " + oldAttributeValue + ",新值為: " + newAttributeValue); // 其他處理邏輯 // ... } }
在上面的例子中,MyServletContextAttributeListener實(shí)現(xiàn)了ServletContextAttributeListener接口,并使用@WebListener注解標(biāo)記為一個(gè)監(jiān)聽(tīng)器。它重寫(xiě)了attributeAdded、attributeRemoved和attributeReplaced方法,在這些方法中可以添加對(duì)ServletContext屬性變化的處理邏輯。
在attributeAdded方法中,當(dāng)ServletContext屬性被添加時(shí),你可以獲取屬性的名稱(chēng)和值,并執(zhí)行相應(yīng)的操作,如記錄日志、更新緩存等。
在attributeRemoved方法中,當(dāng)ServletContext屬性被移除時(shí),你可以獲取屬性的名稱(chēng)和值,并執(zhí)行相應(yīng)的操作,如清理資源、撤銷(xiāo)緩存等。
在attributeReplaced方法中,當(dāng)ServletContext屬性被替換時(shí),你可以同時(shí)獲取屬性的舊值和新值,并執(zhí)行相應(yīng)的操作,如更新緩存、重新加載配置等。
要使監(jiān)聽(tīng)器生效,你可以使用注解方式將監(jiān)聽(tīng)器標(biāo)記為一個(gè)@WebListener,這樣容器會(huì)自動(dòng)識(shí)別和注冊(cè)監(jiān)聽(tīng)器。
或
如果你使用的是web.xml配置文件進(jìn)行部署描述符的配置,則需要在web.xml中添加以下片段:
<listener> <listener-class>com.example.MyServletContextAttributeListener</listener-class> </listener>
這樣,當(dāng)ServletContext屬性發(fā)生變化時(shí),MyServletContextAttributeListener中的相應(yīng)方法就會(huì)被觸發(fā)執(zhí)行。
HttpSessionListener
一個(gè)簡(jiǎn)單的HttpSessionListener示例,展示了當(dāng)HttpSession事件發(fā)生時(shí)執(zhí)行的操作:
import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; @WebListener public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { // 當(dāng)HttpSession被創(chuàng)建時(shí)執(zhí)行的操作 System.out.println("HttpSession被創(chuàng)建,ID: " + se.getSession().getId()); // 其他處理邏輯 // ... } @Override public void sessionDestroyed(HttpSessionEvent se) { // 當(dāng)HttpSession被銷(xiāo)毀時(shí)執(zhí)行的操作 System.out.println("HttpSession被銷(xiāo)毀,ID: " + se.getSession().getId()); // 其他處理邏輯 // ... } }
在上述示例中,MyHttpSessionListener實(shí)現(xiàn)了HttpSessionListener接口,并使用@WebListener注解標(biāo)記為一個(gè)監(jiān)聽(tīng)器。它重寫(xiě)了sessionCreated和sessionDestroyed方法,在這些方法中可以添加對(duì)HttpSession事件的處理邏輯。
在sessionCreated方法中,當(dāng)HttpSession被創(chuàng)建時(shí),你可以獲取HttpSession的ID,并執(zhí)行相應(yīng)的操作,如記錄日志、初始化用戶(hù)會(huì)話(huà)數(shù)據(jù)等。
在sessionDestroyed方法中,當(dāng)HttpSession被銷(xiāo)毀時(shí),你可以獲取HttpSession的ID,并執(zhí)行相應(yīng)的操作,如清理資源、保存用戶(hù)會(huì)話(huà)狀態(tài)等。
要使監(jiān)聽(tīng)器生效,你可以使用注解方式將監(jiān)聽(tīng)器標(biāo)記為一個(gè)@WebListener,這樣容器會(huì)自動(dòng)識(shí)別和注冊(cè)監(jiān)聽(tīng)器。如果你使用的是web.xml配置文件進(jìn)行部署描述符的配置,則需要在web.xml中添加以下片段:
<listener> <listener-class>com.example.MyHttpSessionListener</listener-class> </listener>
這樣,當(dāng)HttpSession事件發(fā)生時(shí),MyHttpSessionListener中的相應(yīng)方法就會(huì)被觸發(fā)執(zhí)行。
HttpSessionAttributeListener
一個(gè)簡(jiǎn)單的HttpSessionAttributeListener示例,展示了當(dāng)HttpSession屬性發(fā)生變化時(shí)執(zhí)行的操作:
import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; @WebListener public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener { @Override public void attributeAdded(HttpSessionBindingEvent event) { // 當(dāng)向HttpSession中添加屬性時(shí)執(zhí)行的操作 System.out.println("屬性已添加:名稱(chēng):" + event.getName() + ",值:" + event.getValue()); // 其他處理邏輯 // ... } @Override public void attributeRemoved(HttpSessionBindingEvent event) { // 當(dāng)從HttpSession中移除屬性時(shí)執(zhí)行的操作 System.out.println("屬性已移除:名稱(chēng):" + event.getName() + ",值:" + event.getValue()); // 其他處理邏輯 // ... } @Override public void attributeReplaced(HttpSessionBindingEvent event) { // 當(dāng)替換HttpSession中的屬性時(shí)執(zhí)行的操作 System.out.println("屬性已替換:名稱(chēng):" + event.getName() + ",舊值:" + event.getValue() + ",新值:" + event.getSession().getAttribute(event.getName())); // 其他處理邏輯 // ... } }
在上述示例中,MyHttpSessionAttributeListener實(shí)現(xiàn)了HttpSessionAttributeListener接口,并使用@WebListener注解標(biāo)記為一個(gè)監(jiān)聽(tīng)器。它重寫(xiě)了attributeAdded、attributeRemoved和attributeReplaced方法,在這些方法中可以添加對(duì)HttpSession屬性變化的處理邏輯。
在attributeAdded方法中,當(dāng)向HttpSession中添加屬性時(shí),你可以獲取屬性的名稱(chēng)和值,并執(zhí)行相應(yīng)的操作,如記錄日志、更新相關(guān)數(shù)據(jù)等。
在attributeRemoved方法中,當(dāng)從HttpSession中移除屬性時(shí),你可以獲取屬性的名稱(chēng)和值,并執(zhí)行相應(yīng)的操作,如記錄日志、清除相關(guān)數(shù)據(jù)等。
在attributeReplaced方法中,當(dāng)替換HttpSession中的屬性時(shí),你可以獲取屬性的名稱(chēng)、舊值和新值,并執(zhí)行相應(yīng)的操作,如記錄日志、更新相關(guān)數(shù)據(jù)等。
要使監(jiān)聽(tīng)器生效,你可以使用注解方式將監(jiān)聽(tīng)器標(biāo)記為一個(gè)@WebListener。
或
如果你使用的是web.xml配置文件進(jìn)行部署描述符的配置,則需要在web.xml中添加以下片段:
<listener> <listener-class>com.example.MyHttpSessionAttributeListener</listener-class> </listener>
這樣,當(dāng)HttpSession屬性發(fā)生變化時(shí),MyHttpSessionAttributeListener中的相應(yīng)方法就會(huì)被觸發(fā)執(zhí)行。
ServletRequestListener
一個(gè)簡(jiǎn)單的ServletRequestListener示例,展示了在每個(gè)頁(yè)面請(qǐng)求到達(dá)和處理完成時(shí)執(zhí)行的操作:
import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; @WebListener public class MyServletRequestListener implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent sre) { // 頁(yè)面請(qǐng)求到達(dá)時(shí)執(zhí)行的操作 System.out.println("收到新請(qǐng)求"); // 記錄請(qǐng)求信息,如URL、參數(shù)等 // ... } @Override public void requestDestroyed(ServletRequestEvent sre) { // 頁(yè)面請(qǐng)求處理完成后執(zhí)行的操作 System.out.println("請(qǐng)求處理完成"); // 清理操作,如釋放資源 // ... } }
在上面的例子中,MyServletRequestListener實(shí)現(xiàn)了ServletRequestListener接口,并使用@WebListener注解標(biāo)記為一個(gè)監(jiān)聽(tīng)器。它重寫(xiě)了requestInitialized和requestDestroyed方法,在這兩個(gè)方法中可以添加自定義的邏輯處理。
在requestInitialized方法中,你可以記錄請(qǐng)求信息,如URL、參數(shù)等。
在requestDestroyed方法中,你可以執(zhí)行清理操作,如釋放資源。
要讓監(jiān)聽(tīng)器生效,你可以使用注解方式將監(jiān)聽(tīng)器標(biāo)記為一個(gè)@WebListener,這樣容器會(huì)自動(dòng)識(shí)別和注冊(cè)監(jiān)聽(tīng)器。
或
如果你使用的是web.xml配置文件進(jìn)行部署描述符的配置,則需要在web.xml中添加以下片段:
<listener> <listener-class>com.example.MyServletRequestListener</listener-class> </listener>
這樣,在每次頁(yè)面請(qǐng)求到達(dá)時(shí),MyServletRequestListener中的邏輯將被觸發(fā)執(zhí)行。同樣,在每個(gè)頁(yè)面請(qǐng)求完成后,requestDestroyed方法也會(huì)被調(diào)用執(zhí)行清理操作。
ServletRequestAttributeListener
一個(gè)簡(jiǎn)單的ServletRequestAttributeListener示例,展示了當(dāng)ServletRequest屬性發(fā)生變化時(shí)執(zhí)行的操作:
import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServletRequest; @WebListener public class MyServletRequestAttributeListener implements ServletRequestAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent event) { // 當(dāng)向ServletRequest中添加屬性時(shí)執(zhí)行的操作 HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); System.out.println("屬性已添加:名稱(chēng):" + event.getName() + ",值:" + event.getValue() + ",請(qǐng)求URL:" + request.getRequestURL()); // 其他處理邏輯 // ... } @Override public void attributeRemoved(ServletRequestAttributeEvent event) { // 當(dāng)從ServletRequest中移除屬性時(shí)執(zhí)行的操作 HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); System.out.println("屬性已移除:名稱(chēng):" + event.getName() + ",值:" + event.getValue() + ",請(qǐng)求URL:" + request.getRequestURL()); // 其他處理邏輯 // ... } @Override public void attributeReplaced(ServletRequestAttributeEvent event) { // 當(dāng)替換ServletRequest中的屬性時(shí)執(zhí)行的操作 HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); System.out.println("屬性已替換:名稱(chēng):" + event.getName() + ",舊值:" + event.getValue() + ",新值:" + request.getAttribute(event.getName()) + ",請(qǐng)求URL:" + request.getRequestURL()); // 其他處理邏輯 // ... } }
在上述示例中,MyServletRequestAttributeListener實(shí)現(xiàn)了ServletRequestAttributeListener接口,并使用@WebListener注解標(biāo)記為一個(gè)監(jiān)聽(tīng)器。它重寫(xiě)了attributeAdded、attributeRemoved和attributeReplaced方法,在這些方法中可以添加對(duì)ServletRequest屬性變化的處理邏輯。
在attributeAdded方法中,當(dāng)向ServletRequest中添加屬性時(shí),你可以獲取屬性的名稱(chēng)和值,并執(zhí)行相應(yīng)的操作,如記錄日志、更新相關(guān)數(shù)據(jù)等。通過(guò)event.getServletRequest()可以獲取到HttpServletRequest對(duì)象,進(jìn)而可以獲取請(qǐng)求的URL等信息。
在attributeRemoved方法中,當(dāng)從ServletRequest中移除屬性時(shí),你可以獲取屬性的名稱(chēng)和值,并執(zhí)行相應(yīng)的操作,如記錄日志、清除相關(guān)數(shù)據(jù)等。同樣,可以通過(guò)event.getServletRequest()獲取到HttpServletRequest對(duì)象。
在attributeReplaced方法中,當(dāng)替換ServletRequest中的屬性時(shí),你可以獲取屬性的名稱(chēng)、舊值和新值,并執(zhí)行相應(yīng)的操作,如記錄日志、更新相關(guān)數(shù)據(jù)等。同樣,通過(guò)event.getServletRequest()可以獲取到HttpServletRequest對(duì)象。
要使監(jiān)聽(tīng)器生效,你可以使用注解方式將監(jiān)聽(tīng)器標(biāo)記為一個(gè)@WebListener。
或
如果你使用的是web.xml配置文件進(jìn)行部署描述符的配置,則需要在web.xml中添加以下片段:
<listener> <listener-class>com.example.MyServletRequestAttributeListener</listener-class> </listener>
這樣,當(dāng)ServletRequest屬性發(fā)生變化時(shí),MyServletRequestAttributeListener中的相應(yīng)方法就會(huì)被觸發(fā)執(zhí)行。
五. 打開(kāi)一個(gè)Tomcat應(yīng)用
在啟動(dòng)Tomcat并自動(dòng)打開(kāi)index.jsp頁(yè)面的過(guò)程中,以下監(jiān)聽(tīng)器將執(zhí)行相應(yīng)的操作:
- ServletContextListener:
- contextInitialized 方法將在Tomcat啟動(dòng)時(shí)執(zhí)行,你可以在此方法中執(zhí)行應(yīng)用程序啟動(dòng)時(shí)的初始化操作,例如加載配置文件、初始化數(shù)據(jù)庫(kù)連接池等。
- contextDestroyed 方法將在Tomcat關(guān)閉時(shí)執(zhí)行,你可以在此方法中執(zhí)行應(yīng)用程序關(guān)閉時(shí)的清理操作,例如關(guān)閉數(shù)據(jù)庫(kù)連接池、釋放資源等。
- ServletRequestListener:
- requestInitialized 方法將在每個(gè)頁(yè)面請(qǐng)求到達(dá)Tomcat時(shí)執(zhí)行,你可以在此方法中記錄請(qǐng)求信息,如URL、參數(shù)等。
- requestDestroyed 方法將在每個(gè)頁(yè)面請(qǐng)求處理完成后執(zhí)行,你可以在此方法中執(zhí)行清理操作,如釋放資源等。
- HttpSessionListener:
- sessionCreated 方法將在每個(gè)新的會(huì)話(huà)被創(chuàng)建時(shí)執(zhí)行,你可以在此方法中記錄用戶(hù)登錄信息、初始化權(quán)限等。
- sessionDestroyed 方法將在每個(gè)會(huì)話(huà)被銷(xiāo)毀時(shí)執(zhí)行,你可以在此方法中執(zhí)行清理會(huì)話(huà)相關(guān)資源、處理用戶(hù)退出等操作。
當(dāng)你在瀏覽器訪(fǎng)問(wèn)Tomcat的根目錄(如 //localhost:8080/)時(shí),以下是一種可能的監(jiān)聽(tīng)器執(zhí)行順序:
- ServletContextListener 的 contextInitialized 方法將被調(diào)用。
- 在這個(gè)方法中,你可以執(zhí)行應(yīng)用程序啟動(dòng)時(shí)的初始化操作,如加載配置文件、初始化數(shù)據(jù)庫(kù)連接池等。
- ServletRequestListener 的 requestInitialized 方法將被調(diào)用。
- 在這個(gè)方法中,你可以記錄請(qǐng)求信息,如URL、參數(shù)等。
- Tomcat 將查找并處理index.jsp頁(yè)面。
- ServletRequestListener 的 requestDestroyed 方法將被調(diào)用。
- 在這個(gè)方法中,你可以執(zhí)行清理操作,如釋放資源等。
- HttpSessionListener 的 sessionCreated 方法將被調(diào)用(如果啟用了會(huì)話(huà))。
- 在這個(gè)方法中,你可以記錄用戶(hù)登錄信息、初始化權(quán)限等。
- 頁(yè)面加載完成并在瀏覽器中呈現(xiàn)。
注意,具體的監(jiān)聽(tīng)器執(zhí)行順序可能會(huì)根據(jù)Tomcat版本、配置和其他因素而有所不同。此外,如果你在應(yīng)用程序中有自定義的監(jiān)聽(tīng)器,那么它們也會(huì)參與監(jiān)聽(tīng)器的執(zhí)行順序。
到此這篇關(guān)于JavaWeb三大組件之監(jiān)聽(tīng)器Listener詳解的文章就介紹到這了,更多相關(guān)監(jiān)聽(tīng)器Listener詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入理解JavaWeb中過(guò)濾器與監(jiān)聽(tīng)器的應(yīng)用
- JavaWeb的監(jiān)聽(tīng)器和過(guò)濾器你了解嗎
- JavaWeb之監(jiān)聽(tīng)器案例講解
- Javaweb監(jiān)聽(tīng)器實(shí)例之統(tǒng)計(jì)在線(xiàn)人數(shù)
- 快速學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法
- 深入學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法
- JavaWeb監(jiān)聽(tīng)器Listener實(shí)例解析
相關(guān)文章
詳解SpringCloud Gateway 2020.0.2最新版
這篇文章主要介紹了SpringCloud Gateway 2020.0.2最新版,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04struts中動(dòng)態(tài)方法調(diào)用使用通配符
這篇文章主要介紹了struts中動(dòng)態(tài)方法調(diào)用使用通配符的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-09-09Spring注解實(shí)現(xiàn)循環(huán)重試功能(適用場(chǎng)景分析)
這篇文章主要介紹了Spring注解實(shí)現(xiàn)循環(huán)重試功能,本篇主要簡(jiǎn)單介紹了Springboot中的Retryable的使用,主要的適用場(chǎng)景和注意事項(xiàng),當(dāng)需要重試的時(shí)候還是很有用的,需要的朋友可以參考下2023-04-04Mybatis插入時(shí)返回自增主鍵方式(selectKey和useGeneratedKeys)
這篇文章主要介紹了Mybatis插入時(shí)返回自增主鍵方式(selectKey和useGeneratedKeys),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Java http加簽、驗(yàn)簽實(shí)現(xiàn)方案詳解
這篇文章主要介紹了Java http加簽、驗(yàn)簽實(shí)現(xiàn)方案詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-07-07Mybatis-Plus可能導(dǎo)致死鎖的問(wèn)題分析及解決辦法
這篇文章給大家主要介紹了Mybatis-Plus可能導(dǎo)致死鎖的問(wèn)題分析及解決辦法,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-12-12SpringBoot使用slf4j日志并輸出到文件中的操作方法
這篇文章主要介紹了SpringBoot使用slf4j日志并輸出到文件中,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08