更新時間:2023-11-10 來源:黑馬程序員 瀏覽量:
什么是過濾器鏈呢?所謂過濾器鏈指的是在一個web應(yīng)用程序當(dāng)中,可 以配置多個過濾器,多個過濾器就形成了一個過濾器鏈。
比如:在我們web服務(wù)器當(dāng)中,定義了兩個過濾器,這兩個過濾器就形成了一個過濾器鏈。
而這個鏈上的過濾器在執(zhí)行的時候會一個一個的執(zhí)行,會先執(zhí)行第一個Filter,放行之后再來執(zhí)行第二 個Filter,如果執(zhí)行到了最后一個過濾器放行之后,才會訪問對應(yīng)的web資源。
訪問完web資源之后,按照我們剛才所介紹的過濾器的執(zhí)行流程,還會回到過濾器當(dāng)中來執(zhí)行過濾器放
行后的邏輯,而在執(zhí)行放行后的邏輯的時候,順序是反著的。
先要執(zhí)行過濾器2放行之后的邏輯,再來執(zhí)行過濾器1放行之后的邏輯,最后在給瀏覽器響應(yīng)數(shù)據(jù)。以上就是當(dāng)我們在web應(yīng)用當(dāng)中配置了多個過濾器,形成了這樣一個過濾器鏈以及過濾器鏈的執(zhí)行順序。下面我們通過idea來驗證下過濾器鏈。
驗證步驟:
1. 在filter包下再來新建一個Filter過濾器類:AbcFilter
2. 在AbcFilter過濾器中編寫放行前和放行后邏輯
3. 配置AbcFilter過濾器攔截請求路徑為:/*
4. 重啟SpringBoot服務(wù),查看DemoFilter、AbcFilter的執(zhí)行日志
AbcFilter過濾器
@WebFilter(urlPatterns = "/*") public class AbcFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Abc 攔截到了請求... 放行前邏輯"); //放行 chain.doFilter(request,response); System.out.println("Abc 攔截到了請求... 放行后邏輯"); } }
DemoFilter過濾器
@WebFilter(urlPatterns = "/*") public class DemoFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("DemoFilter 放行前邏輯....."); //放行請求 filterChain.doFilter(servletRequest,servletResponse); System.out.println("DemoFilter 放行后邏輯....."); } }
打開瀏覽器訪問登錄接口:
通過控制臺日志的輸出,大家發(fā)現(xiàn)AbcFilter先執(zhí)行DemoFilter后執(zhí)行,這是為什么呢?
其實是和過濾器的類名有關(guān)系。以注解方式配置的Filter過濾器,它的執(zhí)行優(yōu)先級是按時過濾器類名的自動排序確定的,類名排名越靠前,優(yōu)先級越高。
假如我們想讓DemoFilter先執(zhí)行,怎么辦呢?答案就是修改類名。
測試:修改AbcFilter類名為XbcFilter,運行程序查看控制臺日志
@WebFilter(urlPatterns = "/*") public class XbcFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Xbc 攔截到了請求...放行前邏輯"); //放行 chain.doFilter(request,response); System.out.println("Xbc 攔截到了請求...放行后邏輯"); } }