JavaWeb三大組件之Filter過濾器詳解
前言 :
攔截請求,過濾響應(yīng)
過濾器(Filter)是Java Web應(yīng)用中的一種組件,它在請求到達(dá)Servlet或JSP之前或者響應(yīng)送回客戶端之前,對請求和響應(yīng)進(jìn)行預(yù)處理和后處理操作。通過使用過濾器,可以對請求進(jìn)行過濾,攔截請求,修改請求參數(shù),在請求被處理之前進(jìn)行一些預(yù)處理操作;同時也可以對響應(yīng)進(jìn)行過濾,對響應(yīng)內(nèi)容進(jìn)行修改,添加一些額外的處理。
一.問題引出
之前我們在做項(xiàng)目的時候, 如果要防止用戶直接訪問已經(jīng)登錄了的界面, 那么我們會用session來進(jìn)行限制, 如果登錄過的人, 就將登錄信息add 到 session, 用戶直接訪問登錄界面的時候就根據(jù)用戶的sessionId進(jìn)行查找, 如果有該用戶, 那么就讓其進(jìn)行訪問, 如果沒有那么就跳轉(zhuǎn)到登錄窗口, 讓其進(jìn)行登錄.
在這個過程中, session相當(dāng)于一個過濾器, 將沒有登錄的人過濾出來, 重新進(jìn)行登錄.
但是這種應(yīng)用只適合一個Servlet, 一個網(wǎng)頁, 沒有高效的進(jìn)行過濾, 所以要尋找一種技術(shù), 可以對多個請求Servlet的請求進(jìn)行過濾, 提高代碼效率, 主要是以下六點(diǎn) :
- 業(yè)務(wù)邏輯分離:過濾器能夠?qū)⑴c業(yè)務(wù)邏輯無關(guān)的通用功能與具體的業(yè)務(wù)邏輯進(jìn)行分離,使得代碼結(jié)構(gòu)更加清晰和易于管理。通過將不同的功能封裝在不同的過濾器中,可以提高代碼的可讀性和可維護(hù)性。
- 代碼復(fù)用性:通過使用過濾器,可以將通用的處理邏輯在多個Servlet或JSP中實(shí)現(xiàn)復(fù)用,避免了在每個Servlet或JSP中重復(fù)編寫相同的代碼片段,提高了代碼的復(fù)用性和開發(fā)效率。
- 通用功能的集中管理:過濾器允許將多個通用功能集中在一起,并在一個地方進(jìn)行管理。這樣可以更好地控制和維護(hù)通用功能,減少了修改和擴(kuò)展的工作量。同時,也方便對某一功能進(jìn)行集中優(yōu)化或調(diào)整。
- 安全性增強(qiáng):過濾器可以用于實(shí)現(xiàn)身份驗(yàn)證、權(quán)限控制等安全功能,對用戶請求進(jìn)行安全過濾,攔截惡意請求,防止跨站腳本(XSS)攻擊和其他網(wǎng)絡(luò)安全威脅。通過統(tǒng)一管理和處理,可以提高Web應(yīng)用的安全性。
- 日志和性能監(jiān)控:過濾器可以用于記錄請求和響應(yīng)的詳細(xì)信息,包括URL、參數(shù)、IP地址等,方便日志記錄和性能監(jiān)控。對于大型應(yīng)用程序,過濾器的日志記錄可以幫助快速定位問題和分析性能瓶頸。
- 請求和響應(yīng)處理的統(tǒng)一性:通過過濾器,可以對請求和響應(yīng)進(jìn)行統(tǒng)一處理和修改。例如,可以對請求參數(shù)進(jìn)行校驗(yàn)和過濾,對響應(yīng)內(nèi)容進(jìn)行處理和封裝,使得請求和響應(yīng)的處理具有一致性和規(guī)范性。
二.Filter的介紹
1. Filter 過濾器它是 JavaWeb 的三大組件之一 (Servlet 程序、 Listener 監(jiān)聽器、 Filter 過 濾器 )
2. Filter 過濾器是 JavaEE 的規(guī)范,是接口
3. Filter 過濾器它的作用是:攔截請求,過濾響應(yīng)。
4. 應(yīng)用場景 、 權(quán)限檢查、 日記操作、 事務(wù)管理
三. 基本原理
四.Filter 過濾器 url-pattern
1 、 url-pattern : Filter 的攔截路徑 , 即瀏覽器在請求什么位置的資源時,過濾器會進(jìn)行攔截過 濾
2. 、精確匹配 <url-pattern>/a.jsp</url-pattern> 對應(yīng)的 請求地址 //ip[ 域名 ]:port/ 工程 路徑 /a.jsp 會攔截
3 、目錄匹配 <url-pattern>/manage/*</url-pattern> 對應(yīng)的 請求地址 //ip[ 域名 ]:port/ 工程路徑 /manage/xx , 即 web 工程 manage 目錄下 所有資源 會攔截
4 、后綴名匹配 <url-pattern>*.jsp</url-pattern> 后綴名可變,比如 *.action *.do 等等對應(yīng) 的請求地址 //ip[ 域名 ]:port/ 工程路徑 /xx.jsp , 后綴名為 .jsp 請求會攔截 5 、 Filter 過濾器它只關(guān)心請求的地址是否匹配,不關(guān)心請求的資源是否存在
五.Filter 過濾器生命周期
Filter(過濾器)在 Web 應(yīng)用程序中具有生命周期,包括初始化和銷毀兩個階段。其生命周期由 Web 容器負(fù)責(zé)管理。
- 初始化階段:
- 當(dāng) Web 容器啟動時,會檢測并創(chuàng)建配置文件(如 web.xml)中定義的 Filter。
- 創(chuàng)建 Filter 實(shí)例,并調(diào)用 init() 方法進(jìn)行初始化。
- 在 init() 方法中,可以進(jìn)行一些一次性的初始化操作,如加載配置文件、創(chuàng)建資源等。
- 請求處理階段:
- 在 Web 應(yīng)用程序啟動后,F(xiàn)ilter 可以攔截、處理和修改來自客戶端的請求和服務(wù)器的響應(yīng)。
- 當(dāng)有請求到達(dá)時,Web 容器會調(diào)用 Filter 的 doFilter() 方法,并傳遞請求和響應(yīng)對象。
- 在 doFilter() 方法中,可以編寫過濾邏輯,檢查請求、修改請求或響應(yīng)的內(nèi)容,以及將請求傳遞給下一個 Filter 或目標(biāo)資源。
- 如果存在多個 Filter,它們會按照 Filter 鏈的順序依次執(zhí)行。
- 銷毀階段:
- 當(dāng) Web 容器關(guān)閉或重啟時,會銷毀已創(chuàng)建的 Filter 實(shí)例。
- 調(diào)用 Filter 的 destroy() 方法進(jìn)行銷毀。
- 在 destroy() 方法中,可以執(zhí)行一些清理操作,如釋放資源、關(guān)閉連接等。
需要注意的是,在 Filter 的生命周期中,init()和destroy()方法僅在 Filter 實(shí)例創(chuàng)建和銷毀時調(diào)用一次,而doFilter()方法每次請求被攔截時都會被調(diào)用。
可以在 Filter 的init()方法中進(jìn)行一些初始化配置的操作,如讀取配置文件、初始化資源等。在destroy()方法中可以釋放資源,做一些清理工作。
利用 Filter 的生命周期,開發(fā)人員可以在請求處理過程中實(shí)現(xiàn)自定義的邏輯,并對請求和響應(yīng)進(jìn)行處理、修改或增強(qiáng)。
同時,Servlet 3.0 引入了注解配置,可以使用@WebFilter注解來配置過濾器,并使用initParams和destroyMethod屬性來設(shè)置初始化參數(shù)和銷毀方法。
@WebFilter(urlPatterns = {"/example"}, initParams = {@WebInitParam(name = "param", value = "value")}) public class MyFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { // 初始化邏輯 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 過濾邏輯 } public void destroy() { // 銷毀邏輯 } }
六.FilterConfig
FilterConfig 接口是在 Servlet 過濾器中使用的一個對象,它提供了用于獲取過濾器配置信息的方法。當(dāng)過濾器被初始化時,Web 容器將會創(chuàng)建一個 FilterConfig 對象,并將其作為參數(shù)傳遞給過濾器的init()方法。
FilterConfig 接口定義了以下方法:
getFilterName()
:獲取過濾器的名稱。
String getFilterName();
getInitParameter(String name)
:根據(jù)參數(shù)名稱獲取初始化參數(shù)的值。
String getInitParameter(String name);
getInitParameterNames()
:獲取所有初始化參數(shù)的名稱。
Enumeration<String> getInitParameterNames();
getServletContext()
:獲取 ServletContext 對象。
ServletContext getServletContext();
FilterConfig 對象的主要作用是在過濾器初始化時,提供過濾器的配置信息、初始化參數(shù)和 servlet 上下文等。
使用 FilterConfig 對象,我們可以獲取過濾器的名稱、獲取指定的初始化參數(shù)值以及獲取 ServletContext 對象,進(jìn)而訪問全局的 Servlet 上下文。
在過濾器的init()方法中,可以通過 FilterConfig 參數(shù)獲取這些信息,并進(jìn)行相應(yīng)的處理和配置。
示例:
public class MyFilter implements Filter { private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; String filterName = filterConfig.getFilterName(); String initParamValue = filterConfig.getInitParameter("initParamName"); Enumeration<String> initParamNames = filterConfig.getInitParameterNames(); ServletContext servletContext = filterConfig.getServletContext(); // 進(jìn)行相關(guān)的初始化操作 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 過濾邏輯 } public void destroy() { // 銷毀邏輯 } }
七.FilterChain 過濾器鏈
過濾器鏈?zhǔn)怯糜诎凑枕樞驁?zhí)行多個過濾器的組件,通過調(diào)用 FilterChain 的doFilter()方法來傳遞請求和響應(yīng),實(shí)現(xiàn)過濾器的協(xié)作和控制流。
FilterChain(過濾器鏈)是在 Web 應(yīng)用程序中使用的一個組件,用于管理多個過濾器的執(zhí)行順序和控制流。
當(dāng)一個請求到達(dá)時,Web 容器將會按照過濾器配置的順序依次調(diào)用每個過濾器的doFilter()方法,形成一個過濾器鏈。
過濾器鏈的作用是讓多個過濾器按照一定順序?qū)φ埱筮M(jìn)行處理和過濾,并將請求傳遞給下一個過濾器,直到達(dá)到最終的目標(biāo)資源(如 Servlet、JSP 等)。
FilterChain 接口定義了以下方法:
doFilter(ServletRequest request, ServletResponse response)
:執(zhí)行下一個過濾器或目標(biāo)資源的邏輯。
void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
在每個過濾器的doFilter()
方法中,可以調(diào)用 FilterChain 的doFilter()
方法來傳遞請求和響應(yīng)給下一個過濾器,或者傳遞給目標(biāo)資源。如果沒有調(diào)用doFilter()
方法,過濾器鏈將會被中斷,請求將不會繼續(xù)傳遞。
示例:
public class MyFilter1 implements Filter { public void init(FilterConfig filterConfig) throws ServletException { // 初始化邏輯 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 過濾邏輯 // 調(diào)用下一個過濾器或目標(biāo)資源 chain.doFilter(request, response); } public void destroy() { // 銷毀邏輯 } } public class MyFilter2 implements Filter { public void init(FilterConfig filterConfig) throws ServletException { // 初始化邏輯 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 過濾邏輯 // 調(diào)用下一個過濾器或目標(biāo)資源 chain.doFilter(request, response); } public void destroy() { // 銷毀邏輯 } }
在上述示例中,有兩個過濾器 MyFilter1 和 MyFilter2,它們按照配置順序執(zhí)行。在每個過濾器的doFilter()
方法中,首先處理自定義的過濾邏輯,然后調(diào)用chain.doFilter(request, response)
來傳遞請求和響應(yīng)給下一個過濾器或目標(biāo)資源。
過濾器鏈的執(zhí)行順序由過濾器的配置順序決定,可以通過修改 web.xml 文件或使用注解配置來定義過濾器的順序。
到此這篇關(guān)于JavaWeb三大組件之Filter過濾器詳解的文章就介紹到這了,更多相關(guān)JavaWeb的Filter過濾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA2020.1個性化設(shè)置的實(shí)現(xiàn)
這篇文章主要介紹了IDEA2020.1個性化設(shè)置的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Spring Boot JPA中java 8 的應(yīng)用實(shí)例
這篇文章主要介紹了Spring Boot JPA中java 8 的應(yīng)用實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02RestTemplate的DELETE及PUT等請求方法使用精講
這篇文章主要為大家介紹了RestTemplate的DELETE及PUT等請求方法的使用精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03