關(guān)于過(guò)濾器Filter的介紹和使用詳解
1.簡(jiǎn)介
在 Java Web 開(kāi)發(fā)中,Filter
是一個(gè)非常重要的組件,用于在請(qǐng)求到達(dá) Servlet 之前或響應(yīng)返回客戶(hù)端之前對(duì)請(qǐng)求和響應(yīng)進(jìn)行預(yù)處理或后處理。
Filter
可以用來(lái)實(shí)現(xiàn)多種功能,如日志記錄、權(quán)限檢查、編碼轉(zhuǎn)換、請(qǐng)求頭修改等。就好比機(jī)場(chǎng)的層層安檢,對(duì)前來(lái)的乘客進(jìn)行檢查過(guò)濾,攜帶違規(guī)物品,未買(mǎi)機(jī)票等不滿(mǎn)足機(jī)場(chǎng)要求的就會(huì)被阻止進(jìn)入。
2.Filter 的工作原理
配置:在 web.xml
文件中或使用注解來(lái)配置 Filter
。
- 在
web.xml
中配置
<filter> <!--設(shè)置filter的別名--> <filter-name>LoggingFilter</filter-name> <!--filter的字節(jié)碼路徑--> <filter-class>com.example.LoggingFilter</filter-class> </filter> <filter-mapping> <!--使用filter別名所對(duì)應(yīng)的過(guò)濾路徑,可以有多個(gè)--> <filter-name>LoggingFilter</filter-name> <!--/*表示對(duì)所有路徑進(jìn)行過(guò)濾--> <url-pattern>/*</url-pattern> <!--所要過(guò)濾的servlet的別名--> <servlet-name>servlet1</servlet-name> </filter-mapping>
使用注解@WebFilter
,它有如下幾個(gè)常用的值:
filterName
: filter的別名相當(dāng)于標(biāo)簽urlPatterns
:所要過(guò)濾的資源url,相當(dāng)于標(biāo)簽ServletNames
:所要過(guò)濾的servlet別名,相當(dāng)于 servletNames
@WebFilter( filterName = "loggingFilter", urlPatterns = {"/servlet1","*.html"}, servletNames = {"servlet1","Servlet2"} )
攔截:
- 當(dāng)請(qǐng)求到達(dá)時(shí),
Filter
會(huì)攔截請(qǐng)求,并執(zhí)行預(yù)處理邏輯。 - 在請(qǐng)求到達(dá)目標(biāo)資源前所執(zhí)行的一些操作,如檢查用戶(hù)是否有權(quán)限訪(fǎng)問(wèn)記錄、請(qǐng)求和響應(yīng)的信息
放行:
Filter
可以選擇是否放行請(qǐng)求到目標(biāo)資源(如 Servlet)。此時(shí)會(huì)執(zhí)行FilterChain
的doFilter
方法代表放行。FilterChain
表示Filter
鏈,若對(duì)于該資源,后續(xù)還有其他Filter
要進(jìn)行過(guò)濾,此時(shí)的doFilter
方法就會(huì)轉(zhuǎn)而執(zhí)行其他的Filter
;若此時(shí)沒(méi)有Filter
要進(jìn)行過(guò)濾,那么便會(huì)放行,進(jìn)行目標(biāo)資源的處理(如,servlet)
后處理:
- 在目標(biāo)資源(如 Servlet)處理完請(qǐng)求后
Filter
可以對(duì)響應(yīng)進(jìn)行后處理
3.Filter的生命周期
包括初創(chuàng)建、始化、過(guò)濾和銷(xiāo)毀四個(gè)階段。
階段 | 對(duì)應(yīng)方法 | 執(zhí)行時(shí)機(jī) | 執(zhí)行次數(shù) |
---|---|---|---|
創(chuàng)建對(duì)象 | 構(gòu)造器 | web應(yīng)用啟動(dòng)時(shí) | 1次 |
初始化方法 | void init(FilterConfig filterConfig) | 構(gòu)造完畢 | 1次 |
過(guò)濾請(qǐng)求 | void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) | 每次請(qǐng)求 | 多次 |
銷(xiāo)毀 | default void destroy() | web應(yīng)用關(guān)閉時(shí) | 1次 |
特別注意的的時(shí)Filter
在web應(yīng)用啟動(dòng)時(shí)就創(chuàng)建了,并且進(jìn)行初始化,這個(gè)過(guò)程只會(huì)出現(xiàn)一次。
4.Filter的執(zhí)行順序
一個(gè)web項(xiàng)目中,可以同時(shí)定義多個(gè)過(guò)濾器,當(dāng)多個(gè)過(guò)濾器對(duì)同一個(gè)資源進(jìn)行過(guò)濾時(shí),工作位置有先后,整體形成一個(gè)工作鏈,稱(chēng)之為過(guò)濾器鏈(FilterChain)
- 當(dāng)使用配置文件進(jìn)行配置時(shí)
- 過(guò)濾器鏈中的過(guò)濾器的順序由<filter-mapping>標(biāo)簽的定義順序決定
- 當(dāng)使用注解的方式進(jìn)行配置時(shí)
- 通常會(huì)把全部的過(guò)濾器放在一個(gè)包下,此時(shí),執(zhí)行順序?yàn)轭?lèi)名的字典排序由小到大依次執(zhí)行
5.一個(gè)簡(jiǎn)單的Filter的示例
案例要求:
當(dāng)用戶(hù)訪(fǎng)問(wèn)資源時(shí),檢查其是否進(jìn)行登陸,若未登錄則跳轉(zhuǎn)到登錄頁(yè), 若以登錄則放行
@WebFilter("/*") public class CheckLoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //向下轉(zhuǎn)型,實(shí)現(xiàn)重定向,獲得session等功能 HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 檢查用戶(hù)是否已登錄 String user = (String) httpRequest.getSession().getAttribute("username"); if (user == null) { // 用戶(hù)未登錄,重定向到登錄頁(yè)面 httpResponse.sendRedirect(httpRequest.getContextPath() + "/login"); } else { // 用戶(hù)已登錄,放行請(qǐng)求,注意是調(diào)用的FilterChain中的doFilter方法??! chain.doFilter(request, response); } } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Spring Boot攔截器Interceptor與過(guò)濾器Filter詳細(xì)教程(示例詳解)
- dubbo3 filter(過(guò)濾器)如何自定義過(guò)濾器
- java中的過(guò)濾器 Filter應(yīng)用小結(jié)
- Java 8 Stream filter流式過(guò)濾器詳解
- Spring過(guò)濾器中OncePerRequestFilter應(yīng)用實(shí)現(xiàn)
- JavaScript中通過(guò)array.filter()實(shí)現(xiàn)數(shù)組的數(shù)據(jù)篩選、數(shù)據(jù)清洗和鏈?zhǔn)秸{(diào)用(JS數(shù)組過(guò)濾器的使用示例)
相關(guān)文章
Java實(shí)現(xiàn)的校驗(yàn)銀行卡功能示例
這篇文章主要介紹了Java實(shí)現(xiàn)的校驗(yàn)銀行卡功能,結(jié)合完整實(shí)例形式分析了java針對(duì)銀行卡類(lèi)型、歸屬地等信息的判斷、讀取相關(guān)操作技巧,需要的朋友可以參考下2018-06-06druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式
這篇文章主要介紹了druid配置數(shù)據(jù)庫(kù)連接使用密文密碼方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,2023-12-12如何在Java SpringBoot項(xiàng)目中配置動(dòng)態(tài)數(shù)據(jù)源你知道嗎
這篇文章主要介紹了SpringBoot如何在運(yùn)行時(shí)動(dòng)態(tài)添加數(shù)據(jù)源,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-09-09

java web監(jiān)聽(tīng)器統(tǒng)計(jì)在線(xiàn)用戶(hù)及人數(shù)

Spring源碼如何修改Bean的屬性用到的相關(guān)類(lèi)