目錄
1. Filter & 過濾器
1.1. 過濾器概述
1.2. 過濾器的使用
1.3. 過濾器生命周期
1.4. 過濾器鏈的使用
1.5. 注解方式配置過濾器
2. Listener & 監聽器
2.1. 監聽器概述
2.2. Java Web的監聽器
2.2.1. 常用監聽器
2.2.1.1. ServletContextListener監聽器
2.2.1.2. ServletContextAttributeListener監聽器
2.2.2. 其他監聽器
2.2.2.1. session域監聽器
2.2.2.2. HttpSessionListener 監聽器
2.2.2.3. HttpSessionAttributeListener 監聽器
2.2.2.4. request域監聽器
2.2.2.5. ServletRequestListener 監聽器
2.2.2.6. ServletRequestAttributeListener 監聽器
2.2.3. session域的兩個特殊監聽器
2.2.3.1. HttpSessionBindingListener 監聽器
2.2.3.2. HttpSessionActivationListener 監聽器
1. Filter & 過濾器
1.1. 過濾器概述
Filter是Java Web開發中的一種技術,它可以對目標資源的請求進行過濾。簡單來說,Filter就像是一個前置處理器或者攔截器,它會在目標資源被請求之前執行,對請求進行一定的處理或者攔截。
- Filter接口是Filter的開發規范,所有開發的Filter都需要實現這個接口。當一個請求到達Filter時,容器會先創建一個HttpServletRequest和HttpServletResponse對象,然后調用Filter的doFilter方法。
- doFilter方法決定了一個請求是否可以繼續執行。如果doFilter方法允許請求繼續,那么請求將會被轉發到目標資源。如果doFilter方法拒絕了請求,那么請求就會在這個Filter中停止,由Filter自己對請求做出響應。
- 除了對請求進行過濾,Filter也可以在目標資源響應之前對響應進行再次處理。因此,Filter不僅可以用于對請求的過濾,也可以用于對響應的處理。
- Filter是GOF(設計模式)中責任鏈模式的典型案例。責任鏈模式是指多個對象形成一個處理請求的鏈條,每個對象都有機會處理請求,直到有一個對象處理了請求為止。
- Filter的常用應用非常廣泛,包括但不限于登錄權限檢查、解決網站亂碼、過濾敏感字符、日志記錄、性能分析等。這些應用都是通過Filter技術實現的。
舉個例子:
生活舉例中,公司前臺、停車場安保和地鐵驗票閘機都是Filter的典型應用。它們都可以對進入的人員或者車輛進行審核和過濾。如果符合條件,就放行;如果不符合條件,就拒絕進入。同時,它們也可以在人員或者車輛離開時進行再次審核和收費。
Filter工作原理圖解:
Filter接口API:
從IDEA上面的Filter.java上扒下來的源碼,也就三個抽象方法:
- init(FilterConfig filterConfig):這是過濾器初始化時調用的方法。在這個方法中,可以設置過濾器的一些配置信息,如參數等。默認的實現是不執行任何操作。
- doFilter(ServletRequest request, ServletResponse response, FilterChain chain):這是過濾器的主要工作方法。每次客戶端請求資源時,都會調用此方法。在這個方法中,可以根據需要修改請求和響應對象,并決定是否將請求傳遞給下一個過濾器或目標資源。這通常涉及檢查請求,可能修改請求或響應,然后調用chain.doFilter()來繼續過濾器鏈,最后可能直接在響應上設置頭信息。
- destroy():這是過濾器被移除服務時調用的方法。在這個方法中,可以進行一些清理工作,例如釋放資源,確保所有持久狀態與內存中的當前狀態同步。默認的實現同樣不執行任何操作。
1.2. 過濾器的使用
目標:開發一個日志記錄過濾器
- 用戶請求到達目標資源之前,記錄用戶的請求資源路徑
- 響應之前記錄本次請求目標資源運算的耗時
- 可以選擇將日志記錄進入文件,為了方便測試,這里將日志直接在控制臺打印
LoggingFilter.java 過濾器
package filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;public class LoggingFilter implements Filter { //實現Filter接口public void init(FilterConfig config) throws ServletException {System.out.println("以啟用登錄過濾器~");}private final SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 參數父轉子HttpServletRequest request =(HttpServletRequest) servletRequest;HttpServletResponse response =(HttpServletResponse) servletResponse;// 拼接日志文本String requestURI = request.getRequestURI();String time = dateFormat.format(new Date());String beforeLogging =requestURI+"在"+time+"被請求了";// 打印日志System.out.println(beforeLogging);// 獲取系統時間long t1 = System.currentTimeMillis();// 放行請求filterChain.doFilter(request,response);// 獲取系統時間long t2 = System.currentTimeMillis();// 拼接日志文本String afterLogging =requestURI+"在"+time+"的請求耗時:"+(t2-t1)+"毫秒";// 打印日志System.out.println(afterLogging);}@Overridepublic void destroy() {System.out.println("以銷毀登錄過濾器~");}
}
配置web.xml
不配置web.xml就是普通的java類,無法實現filter過濾器的功能
<?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"><!--配置過濾器--><filter> <filter-name>loggingFilter</filter-name> <!--過濾器名稱--><filter-class>filter.LoggingFilter</filter-class> <!--過濾器類名--></filter><filter-mapping> <filter-name>loggingFilter</filter-name> <!--過濾器名稱--><url-pattern>/*</url-pattern> <!--過濾器攔截的url,/* 表示對所有資源進行過濾--></filter-mapping></web-app>
說明:
ServletA.java
package servlet;import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/servletA")
public class ServletA extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp){// 處理器請求System.out.println("servletA處理請求的方法,耗時10毫秒");// 模擬處理請求耗時try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
ServletB.java
package servlet;import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/servletB")
public class ServletB extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp){// 處理器請求System.out.println("servletB處理請求的方法,耗時15毫秒");// 模擬處理請求耗時try {Thread.sleep(15);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
啟動服務器
1.3. 過濾器生命周期
Filter在Web項目中是一個重要的組件,其生命周期與Servlet有些類似,但也有一些區別。
- 創建(Creation):Filter對象在系統啟動時就會被創建。不像Servlet需要配置load-on-startup參數才能實現系統啟動時立即創建,Filter的創建是默認行為,系統啟動時就會立即創建Filter對象。
- 初始化(Initialization):在Filter對象創建后,會調用其init方法進行初始化。這個過程通常會接收一個FilterConfig對象作為參數,通過這個對象可以獲取到Filter的配置信息。
- 執行(Execution):初始化完成后,Filter就可以開始執行其任務。在Web應用中,Filter通常被用來執行一些通用的操作,如日志記錄、數據壓縮、認證授權等。Filter的執行順序是根據其在web.xml中的配置順序來決定的。
- 銷毀(Destroy):當Web應用關閉或重啟時,Filter的生命周期結束,會調用其destroy方法進行資源清理。
階段 | 對應方法 | 執行時機 | 執行次數 |
創建對象 | 構造器 | web應用啟動時 | 1 |
初始化方法 | void init(FilterConfig filterConfig) | 構造完畢 | 1 |
過濾請求 | void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) | 每次請求 | 多次 |
銷毀 | default void destroy() | web應用關閉時 | 1次 |
1.4. 過濾器鏈的使用
過濾器鏈概述:
在一個Web項目中,可以定義多個過濾器(Filter)。這些過濾器可以同時存在,并且可以對同一個資源進行過濾操作。這些過濾器按照一定的順序形成一個工作鏈,這個工作鏈被稱為過濾器鏈(Filter Chain)。
- 過濾器鏈中的過濾器的順序是由filter-mapping的配置順序決定的。在web.xml文件中,我們可以配置多個filter-mapping,每個filter-mapping定義了一個過濾器及其對應的匹配規則。這些過濾器按照filter-mapping的順序依次執行。
- 每個過濾器都有其特定的過濾范圍。對于同一個資源來說,可能需要經過多個過濾器的過濾。因此,過濾器鏈中的過濾器個數可能會因為資源的不同而有所差異。
- 另外,如果某個過濾器是使用ServletName進行匹配規則的配置,那么這個過濾器的執行優先級相對較低。這意味著,當一個請求到達時,過濾器鏈會先執行那些使用ServletName進行匹配規則配置的過濾器,然后再執行其他過濾器。
示例:
如果定義了三個過濾器Filter1、Filter2、Filter3,執行順序也是1、2、3
這里Filter的代碼就不舉例了,關鍵在于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"><filter><filter-name>filter1</filter-name><filter-class>filters.Filter1</filter-class></filter><filter><filter-name>filter2</filter-name><filter-class>filters.Filter2</filter-class></filter><filter><filter-name>filter3</filter-name><filter-class>filters.Filter3</filter-class></filter><!--filter-mapping的順序決定了過濾器的工作順序--><filter-mapping><filter-name>filter1</filter-name><url-pattern>/servletC</url-pattern></filter-mapping><filter-mapping><filter-name>filter2</filter-name><url-pattern>/servletC</url-pattern></filter-mapping><filter-mapping><filter-name>filter3</filter-name><url-pattern>/servletC</url-pattern></filter-mapping>
</web-app>
1.5. 注解方式配置過濾器
注解方式配置過濾器是指在Java Web應用程序中使用注解來定義和配置過濾器。
和servlet注解類似,通過注解,可以省略web.xml配置文件,直接在Java類中聲明過濾器。
Filter注解源碼(還是從IDEA上面復制下來的):
package javax.servlet.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.servlet.DispatcherType;/*** Annotation used to declare a servlet filter.** <p>This annotation is processed by the container at deployment time,* and the corresponding filter applied to the specified URL patterns,* servlets, and dispatcher types.* * @see javax.servlet.Filter** @since Servlet 3.0*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebFilter {/*** The description of the filter* * @return the description of the filter*/String description() default "";/*** The display name of the filter** @return the display name of the filter*/String displayName() default "";/*** The init parameters of the filter** @return the init parameters of the filter*/WebInitParam[] initParams() default {};/*** The name of the filter** @return the name of the filter*/String filterName() default "";/*** The small-icon of the filter** @return the small-icon of the filter*/String smallIcon() default "";/*** The large-icon of the filter** @return the large-icon of the filter*/String largeIcon() default "";/*** The names of the servlets to which the filter applies.** @return the names of the servlets to which the filter applies*/String[] servletNames() default {};/*** The URL patterns to which the filter applies* The default value is an empty array.** @return the URL patterns to which the filter applies*/String[] value() default {};/*** The URL patterns to which the filter applies** @return the URL patterns to which the filter applies*/String[] urlPatterns() default {};/*** The dispatcher types to which the filter applies** @return the dispatcher types to which the filter applies*/DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};/*** Declares whether the filter supports asynchronous operation mode.** @return {@code true} if the filter supports asynchronous operation mode* @see javax.servlet.ServletRequest#startAsync* @see javax.servlet.ServletRequest#startAsync(ServletRequest,* ServletResponse)*/boolean asyncSupported() default false;}
對源碼進行分析:
@Target({ElementType.TYPE})
: 這個注解只能應用于類級別。@Retention(RetentionPolicy.RUNTIME)
: 這個注解將在運行時保留,在運行時可以被反射API讀取。@Documented
: 這個注解會被包含在用戶的JavaDoc中。String description() default "";
: 返回過濾器的描述,默認為空字符串。String displayName() default "";
: 返回過濾器的顯示名稱,默認為空字符串。WebInitParam[] initParams() default {};
: 返回過濾器的初始化參數,默認為一個空數組。String filterName() default "";
: 返回過濾器的名字,默認為空字符串。String smallIcon() default "";
: 返回過濾器的小圖標,默認為空字符串。String largeIcon() default "";
: 返回過濾器的大圖標,默認為空字符串。String[] servletNames() default {};
: 返回過濾器應用到的Servlet名字,默認為一個空數組。String[] value() default {};
: 和urlPatterns()
方法相同,返回過濾器應用到的URL模式,默認為一個空數組。String[] urlPatterns() default {};
: 返回過濾器應用到的URL模式,默認為一個空數組。DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};
: 返回過濾器應用到的調度類型,默認為REQUEST。boolean asyncSupported() default false;
: 聲明過濾器是否支持異步操作模式,默認為false。
代碼示例:
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter(filterName = "MyFilter", urlPatterns = {"/welcome"})
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化操作,如讀取配置參數等}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("Before processing request");// 調用下一個過濾器或servletchain.doFilter(request, response);System.out.println("After processing request");}@Overridepublic void destroy() {// 清理資源等}
}
2. Listener & 監聽器
2.1. 監聽器概述
Listener 監聽器是 JavaWeb 應用程序中的一種組件,它是 Servlet、Filter 和 Listener 這三個組件之一。Listener 是 Java EE 規范中的一部分,它是一個接口,用于監聽特定事件或變化,并在觸發時執行相應的任務。
監聽器的作用是監聽特定的對象或事件,例如對象的創建/銷毀或屬性變化等,當這些事件發生時,監聽器會觸發對應的方法來完成相應的任務。
有八個常用的監聽器
其中最常用的是 ServletContextListener和ServletContextAttributeListener
舉個例子:
監聽器可以比喻為“報警器”。比如我們在家里安裝的煙霧報警器,當煙霧達到一定濃度時,報警器就會發出警報,提醒我們可能有火災隱患。這個報警器就是“監聽器”,它監聽的是煙霧濃度這個事件。當煙霧濃度達到設定閾值時,它就會觸發警報。
在JavaWeb應用程序中,監聽器也是類似的原理。比如ServletContextListener,它監聽的是ServletContext對象的變化。當ServletContext對象創建或銷毀時,ServletContextListener就會觸發對應的方法來完成相應的任務。
監聽器分類:
根據所監聽的對象和事件的不同,可以將監聽器大致分為以下幾類:
- 按監聽的對象劃分:
- Application域監聽器:這類監聽器監聽的是ServletContext對象,其中包括ServletContextListener和ServletContextAttributeListener。ServletContextListener用于監聽ServletContext對象的創建和銷毀事件,而ServletContextAttributeListener則用于監聽ServletContext對象屬性的變化。
- Session域監聽器:這類監聽器監聽的是HttpSession對象,其中包括HttpSessionListener、HttpSessionAttributeListener和HttpSessionBindingListener。HttpSessionListener用于監聽HttpSession對象的創建和銷毀事件,HttpSessionAttributeListener用于監聽HttpSession對象屬性的變化,而HttpSessionBindingListener則用于監聽HttpSession對象綁定和解綁事件。
- Request域監聽器:這類監聽器監聽的是ServletRequest對象,其中包括ServletRequestListener和ServletRequestAttributeListener。ServletRequestListener用于監聽ServletRequest對象的創建和銷毀事件,ServletRequestAttributeListener用于監聽ServletRequest對象屬性的變化。
- 按監聽的事件劃分:
- 域對象的創建和銷毀監聽器:這類監聽器包括ServletContextListener、HttpSessionListener和ServletRequestListener,它們分別用于監聽ServletContext、HttpSession和ServletRequest對象的創建和銷毀事件。
- 域對象數據增刪改事件監聽器:這類監聽器包括ServletContextAttributeListener、HttpSessionAttributeListener和ServletRequestAttributeListener,它們分別用于監聽ServletContext、HttpSession和ServletRequest對象屬性的變化事件。
- 其他監聽器:這類監聽器包括HttpSessionBindingListener和HttpSessionActivationListener等,它們分別用于監聽HttpSession對象綁定和解綁事件以及激活事件等。
2.2. Java Web的監聽器
2.2.1. 常用監聽器
在Java Web監聽器中,常用的監聽器是
ServletContextListener 和 ServletContextAttributeListener
ServletContextListener: 這個接口提供了一個監聽器,可以監聽ServletContext對象的創建和銷毀事件。當Web應用程序啟動時,會創建一個ServletContext對象,而在應用程序關閉時,該對象將被銷毀。通過實現ServletContextListener接口,可以在這兩個關鍵時刻執行特定的操作。例如,可以在ServletContext對象創建時初始化一些全局變量或執行其他必要的設置,或在對象銷毀時進行資源清理。
ServletContextAttributeListener: 這個接口提供了一個監聽器,可以監聽ServletContext屬性(即在ServletContext對象中存儲的屬性)的添加和移除事件。可以通過實現這個接口來監聽特定屬性的添加或移除操作,并在這些操作發生時執行特定的操作。例如,當某個屬性被添加到ServletContext時,可以進行一些初始化操作;當某個屬性被移除時,可以執行一些清理操作。
2.2.1.1. ServletContextListener監聽器
ServletContextListener監聽器:監聽ServletContext對象的創建與銷毀
ServletContextListener本身就是一個接口,繼承EventListener接口
相關方法:
方法名 | 作用 |
contextInitialized(ServletContextEvent sce) | ServletContext創建時調用 |
contextDestroyed(ServletContextEvent sce) | ServletContext銷毀時調用 |
ServletContextListener的源碼,一個繼承與EventListener的接口
package javax.servlet;import java.util.EventListener;public interface ServletContextListener extends EventListener {/*** Receives notification that the web application initialization* process is starting.** <p>All ServletContextListeners are notified of context* initialization before any filters or servlets in the web* application are initialized.** @param sce the ServletContextEvent containing the ServletContext* that is being initialized** @implSpec* The default implementation takes no action.*/default public void contextInitialized(ServletContextEvent sce) {}/*** Receives notification that the ServletContext is about to be* shut down.** <p>All servlets and filters will have been destroyed before any* ServletContextListeners are notified of context* destruction.** @param sce the ServletContextEvent containing the ServletContext* that is being destroyed** @implSpec* The default implementation takes no action.*/default public void contextDestroyed(ServletContextEvent sce) {}
}
代碼舉例:
ServletContextListenerA.java
package listener;import javax.servlet.ServletContextListener;public class ServletContextListenerA implements ServletContextListener {@Overridepublic void contextInitialized(javax.servlet.ServletContextEvent sce) {System.out.println("ServletContextListenerA被創建");}@Overridepublic void contextDestroyed(javax.servlet.ServletContextEvent sce) {System.out.println("ServletContextListenerA已銷毀");}
}
配置 web.xml
啟動服務器:
停止服務器:
小總結:
- 當一個類實現了ServletContextListener接口,它就變成了一個監聽器。ServletContextListener是Java Servlet API的一部分,它能夠監聽ServletContext的創建和銷毀事件。
- 這個類可以監聽的事件由它實現的監聽接口決定。如果一個類實現了ServletContextListener,那么這個類就可以監聽ServletContext的創建和銷毀事件。也就是說,當web應用啟動時,ServletContext對象被創建,以及當web應用關閉時,ServletContext對象被銷毀,這些事件都可以被監聽。
- ServletContextListenerA是一個實現了ServletContextListener接口的類,因此它也是一個監聽器。當web應用啟動時,會產生一個ServletContextEvent事件,這個事件會調用監聽器的對應事件處理方法contextInitialized。同時,會傳遞一個事件對象給這個方法。
- 程序員可以通過這個事件對象,來獲取需要的信息,然后再進行業務處理。例如,他們可以通過這個對象獲取關于ServletContext的信息,以及關于事件類型和其他相關屬性的信息。
- Tomcat知道這個監聽器存在是因為我們需要在web.xml中配置它。在web.xml文件中,我們可以定義ServletContextListener,當Tomcat加載web應用時,它會讀取這個文件并加載所有的ServletContextListener。這樣,當web應用啟動或關閉時,Tomcat就會調用這些監聽器的事件處理方法。
總的來說,ServletContextListener是Java Servlet API的一部分,它允許我們監聽web應用的生命周期事件。我們可以通過實現這個接口來創建自己的監聽器,并在web.xml中配置它,以便Tomcat知道它的存在。
2.2.1.2. ServletContextAttributeListener監聽器
ServletContextAttributeListener監聽器:監聽ServletContext中屬性的添加、移除和修改
ServletContextAttributeListener本身也是一個接口,繼承EventListener接口
相關方法:
方法名 | 作用 |
attributeAdded(ServletContextAttributeEvent scab) | 向ServletContext中添加屬性時調用 |
attributeRemoved(ServletContextAttributeEvent scab) | 從ServletContext中移除屬性時調用 |
attributeReplaced(ServletContextAttributeEvent scab) | 當ServletContext中的屬性被修改時調用 |
ServletContextAttributeListener的源碼:
package javax.servlet;import java.util.EventListener;public interface ServletContextAttributeListener extends EventListener {/*** Receives notification that an attribute has been added to the* ServletContext.** @param event the ServletContextAttributeEvent containing the* ServletContext to which the attribute was added, along with the* attribute name and value** @implSpec* The default implementation takes no action.*/default public void attributeAdded(ServletContextAttributeEvent event) {}/*** Receives notification that an attribute has been removed* from the ServletContext.** @param event the ServletContextAttributeEvent containing the* ServletContext from which the attribute was removed, along with* the attribute name and value** @implSpec* The default implementation takes no action.*/default public void attributeRemoved(ServletContextAttributeEvent event) {}/** Receives notification that an attribute has been replaced* in the ServletContext.** @param event the ServletContextAttributeEvent containing the* ServletContext in which the attribute was replaced, along with* the attribute name and its old value** @implSpec* The default implementation takes no action.*/default public void attributeReplaced(ServletContextAttributeEvent event) {}
}
代碼舉例:
ServletContextAttributeListener01.java
package listener;import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;public class ServletContextAttributeListener01 implements ServletContextAttributeListener {@Override // 監聽ServletContext添加屬性public void attributeAdded(ServletContextAttributeEvent sce) {System.out.println("ServletContextAttributeListener01監聽到了添加屬性" +sce.getName() + "的值");}@Override // 監聽ServletContext移除屬性public void attributeRemoved(javax.servlet.ServletContextAttributeEvent sce) {System.out.println("ServletContextAttributeListener01監聽到了移除屬性" +sce.getName() + "的值");}@Override // 監聽ServletContext替換屬性public void attributeReplaced(javax.servlet.ServletContextAttributeEvent sce) {System.out.println("ServletContextAttributeListener01監聽到了替換屬性" +sce.getName() + "的值");}}
ServletA.java
package servlet;import javax.servlet.ServletContext;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/servletA") //這里servlet用的注解,不用在web.xml配置
public class ServletA extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp){//給ServletContext添加屬性ServletContext servletContext = req.getServletContext();servletContext.setAttribute("name", "Tom");servletContext.setAttribute("name", "Jerry");servletContext.removeAttribute("name");System.out.println("ServletA處理完畢...");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp){doPost(req, resp);}
}
配置web.xml
啟動服務器
2.2.2. 其他監聽器
除了ServletContextListener和ServletContextAttributeListener,其他的監聽器用的比較少
2.2.2.1. session域監聽器
2.2.2.2. HttpSessionListener 監聽器
作用:HttpSessionListener 是一個監聽器,用來監聽 HTTP 會話的創建和銷毀。
當一個 HTTP 會話被創建或銷毀時,它就會觸發相應的事件,我們可以編寫代碼來響應這些事件。
例如,在會話創建時,我們可以進行一些初始化操作;在會話銷毀時,我們可以釋放一些資源。這樣,我們就可以在用戶的狀態變化時,做出相應的處理。
HttpSessionListener的源碼:
package javax.servlet.http;import java.util.EventListener;public interface HttpSessionListener extends EventListener {/** * Receives notification that a session has been created.** @implSpec* The default implementation takes no action.** @param se the HttpSessionEvent containing the session*/default public void sessionCreated(HttpSessionEvent se) {}/** * Receives notification that a session is about to be invalidated.** @implSpec* The default implementation takes no action.** @param se the HttpSessionEvent containing the session*/default public void sessionDestroyed(HttpSessionEvent se) {}
}
相關方法:
方法名 | 作用 |
sessionCreated(HttpSessionEvent se) | 創建session時調用 |
sessionDestroyed(HttpSessionEvent se) | 銷毀session時調用 |
2.2.2.3. HttpSessionAttributeListener 監聽器
作用:HttpSessionAttributeListener 是一個用于監聽 HTTP 會話屬性變化的監聽器。
這意味著,當會話中的屬性發生添加、刪除或修改時,這個監聽器會接收到通知。
HttpSessionAttributeListener源碼:
package javax.servlet.http;import java.util.EventListener;public interface HttpSessionAttributeListener extends EventListener {/*** Receives notification that an attribute has been added to a* session.** @param event the HttpSessionBindingEvent containing the session* and the name and value of the attribute that was added*/default public void attributeAdded(HttpSessionBindingEvent event) {}/*** Receives notification that an attribute has been removed from a* session.** @param event the HttpSessionBindingEvent containing the session* and the name and value of the attribute that was removed*/default public void attributeRemoved(HttpSessionBindingEvent event) {}/*** Receives notification that an attribute has been replaced in a* session.** @param event the HttpSessionBindingEvent containing the session* and the name and (old) value of the attribute that was replaced*/default public void attributeReplaced(HttpSessionBindingEvent event) {}}
相關方法:
方法名 | 作用 |
attributeAdded(HttpSessionBindingEvent event) | 向HttpSession添加屬性時調用 |
attributeRemoved(HttpSessionBindingEvent event) | 向HttpSession移除屬性時調用 |
attributeReplaced(HttpSessionBindingEvent event) | 向HttpSession替換屬性時調用 |
2.2.2.4. request域監聽器
2.2.2.5. ServletRequestListener 監聽器
作用:監聽 Request 創建或銷毀,即Request生命周期監聽。
ServletRequestListener的源碼:
package javax.servlet;import java.util.EventListener;public interface ServletRequestListener extends EventListener {/*** Receives notification that a ServletRequest is about to go out* of scope of the web application.** @param sre the ServletRequestEvent containing the ServletRequest* and the ServletContext representing the web application** @implSpec* The default implementation takes no action.*/default public void requestDestroyed(ServletRequestEvent sre) {}/*** Receives notification that a ServletRequest is about to come* into scope of the web application.** @param sre the ServletRequestEvent containing the ServletRequest* and the ServletContext representing the web application** @implSpec* The default implementation takes no action.*/default public void requestInitialized(ServletRequestEvent sre) {}
}
相關方法:
方法名 | 作用 |
requestDestroyed(ServletRequestEvent sre) | 創建request時調用 |
requestInitialized(ServletRequestEvent sre) | 銷毀request時調用 |
2.2.2.6. ServletRequestAttributeListener 監聽器
作用:ServletRequestAttributeListener 監聽器可以監聽 ServletRequest 對象中的屬性變化。當屬性被添加、移除或替換時,這個監聽器會收到通知并執行相應的操作。
ServletRequestAttributeListener 源碼:
package javax.servlet;import java.util.EventListener;public interface ServletRequestAttributeListener extends EventListener {/*** Receives notification that an attribute has been added to the* ServletRequest.** @param srae the ServletRequestAttributeEvent containing the * ServletRequest and the name and value of the attribute that was* added** @implSpec* The default implementation takes no action.*/default public void attributeAdded(ServletRequestAttributeEvent srae) {}/*** Receives notification that an attribute has been removed from the* ServletRequest.** @param srae the ServletRequestAttributeEvent containing the * ServletRequest and the name and value of the attribute that was* removed** @implSpec* The default implementation takes no action.*/default public void attributeRemoved(ServletRequestAttributeEvent srae) {}/*** Receives notification that an attribute has been replaced on the* ServletRequest.** @param srae the ServletRequestAttributeEvent containing the * ServletRequest and the name and (old) value of the attribute* that was replaced** @implSpec* The default implementation takes no action.*/default public void attributeReplaced(ServletRequestAttributeEvent srae) {}
}
相關方法:
方法名 | 作用 |
attributeAdded(ServletRequestAttributeEvent srae) | 向Request添加屬性時調用 |
attributeRemoved(ServletRequestAttributeEvent srae) | 向Request移除屬性時調用 |
attributeReplaced(ServletRequestAttributeEvent srae) | 向Request替換屬性時調用 |
2.2.3. session域的兩個特殊監聽器
2.2.3.1. HttpSessionBindingListener 監聽器
HttpSessionBindingListener 監聽器也叫session綁定監聽器
作用:HttpSessionBindingListener 監聽 HttpSession 中對象的添加和移除,以確保數據的準確性和一致性。它可以幫助我們跟蹤數據變化并觸發相應操作。
HttpSessionBindingListener 監聽器用于監聽某個對象在 HttpSession 中的添加和移除操作。當該對象被添加到 HttpSession 中或從 HttpSession 中移除時,監聽器會自動執行相應的操作。這個監聽器通常用于管理在 HttpSession 中存儲的數據,確保數據的一致性和準確性。
簡單來說,它可以幫助我們跟蹤 HttpSession 中數據的變化,并觸發相應的操作。
HttpSessionBindingListener源碼:
package javax.servlet.http;import java.util.EventListener;public interface HttpSessionBindingListener extends EventListener {/**** Notifies the object that it is being bound to* a session and identifies the session.** @implSpec* The default implementation takes no action.* * @param event the event that identifies the* session ** @see #valueUnbound**/ default public void valueBound(HttpSessionBindingEvent event) {}/**** Notifies the object that it is being unbound* from a session and identifies the session.** @implSpec* The default implementation takes no action.** @param event the event that identifies* the session * * @see #valueBound**/default public void valueUnbound(HttpSessionBindingEvent event) {}
}
相關方法:
方法名 | 作用 |
valueBound(HttpSessionBindingEvent event) | 該類的實例被放到Session域中時調用 |
void valueUnbound(HttpSessionBindingEvent event) | 該類的實例從Session中移除時調用 |
2.2.3.2. HttpSessionActivationListener 監聽器
HttpSessionActivationListener 監聽器也叫鈍化活化監聽器
作用:HttpSessionActivationListener 監聽 HttpSession 中對象的序列化和反序列化。在分布式系統中,它幫助處理對象的存儲和恢復,允許在序列化和反序列化時執行特定操作。
HttpSessionActivationListener 的源碼:
package javax.servlet.http;import java.util.EventListener;public interface HttpSessionActivationListener extends EventListener { /*** Notification that the session is about to be passivated.** @implSpec* The default implementation takes no action.* * @param se the {@link HttpSessionEvent} indicating the passivation* of the session*/default public void sessionWillPassivate(HttpSessionEvent se) {}/*** Notification that the session has just been activated.** @implSpec* The default implementation takes no action.* * @param se the {@link HttpSessionEvent} indicating the activation* of the session*/default public void sessionDidActivate(HttpSessionEvent se) {}
}
相關方法:
方法名 | 作用 |
sessionWillPassivate(HttpSessionEvent se) | 該類實例和Session一起鈍化到硬盤時調用 |
sessionDidActivate(HttpSessionEvent se) | 該類實例和Session一起活化到內存時調用 |