目錄
Filter過濾器
1. Filter的生命周期
2.Filter的配置
3.攔截路徑
4.攔截具體的使用
?5.攔截方式配置(資源被訪問方式)
6.FilterChain攔截鏈
Filter過濾器
????? filter是過濾器,相比于Servlet的發送請求,filter是用于攔截請求。比如在登陸系統中,正常登陸的用戶可以訪問服務器的相關資源,而如果登陸信息錯誤,則攔截想要訪問資源的請求。以下將具體介紹filter
1. Filter的生命周期
Filter的生命周期分為三部分,分別是init()初始化;doFilter()執行攔截;destroy()銷毀;
具體如下代碼
package com.company.Filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//注解配置實現所有請求訪問都進行攔截
@WebFilter("/*")
public class filterDemo1 implements Filter {
// 初始化@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("加載的時候自動執行,并且只執行一次");}
// 執行攔截@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("實現攔截的時候執行函數,可以多次執行");}
// 銷毀@Overridepublic void destroy() {System.out.println("在服務器關閉的時候,執行銷毀函數");}
}
2.Filter的配置
Filter的配置分為兩種,一種是xml配置,一種是通過注解類配置
- 通過xml配置(打開web.xml):
<filter>
<!-- 隨便創建想要的名稱--><filter-name>filterDemo1</filter-name>
<!-- filter對應的具體類--><filter-class>com.company.Filter.filterDemo1</filter-class></filter>
<!-- 創建filter對應的映射--><filter-mapping>
<!-- filter對應的名稱--><filter-name>filterDemo1</filter-name>
<!-- 攔截路徑,/*表示所有訪問都會進行攔截--><url-pattern>/*</url-pattern></filter-mapping>
- 通過注解類進行配置:
@WebFilter(value=url-pattern)
如果只需要寫攔截規路徑可以省略掉value = ;
直接輸入@WebFilter("/*")實現對數據所有訪問時候進行攔截
3.攔截路徑
剛才介紹了/*是所有請求的攔截,但是對于具體訪問的請求的攔截還無法做到,下面介紹其他攔截路徑
- 具體路徑訪問的攔截:/index.jsp (當訪問index.jsp文件時候實現攔截)
- 某一個目錄的訪問的攔截:/user (當訪問user目錄以下的所有文件時候進行攔截)
- 后綴名訪問的攔截:*.jsp (實現對所有文件以.jsp后綴結尾訪問的攔截)
- 攔截所有相關路徑:/*???? (訪問所有服務器的資源時候都實現攔截)
4.攔截具體的使用
1.創建類實現Filter接口(注意Filter接口是包javax.servlet中的)
2.覆寫生命周期函數
3.通過doFilter函數實現攔截。當通過后實現放行
案例代碼:
攔截類
package com.company.Filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;//通過注解類實現攔截路徑
@WebFilter("/*")
//實現接口
public class filterDemo2 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("過濾器已被加載");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("發現請求,實施攔截");進行驗證,如果通過則實現放行
// System.out.println("驗證成功,放行");
// filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("服務器關閉時候執行銷毀函數");}
}
模擬資源類
package com.company;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/FilterDemo3")
public class FilterDemo3 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("訪問到資源啦");}
// 方法統一@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}
}
當通過url訪問資源類時候 可以看到請求被攔截了,無法執行資源類中輸出"訪問資源類啦"
再加上驗證功能后如果允許通過則需要放行,執行FilterChain filterChain中filterChain對象的doFilter(servletRequest對象, servletResponse對象)即代碼中的
// 攔截結束后如果通過則實現放行System.out.println("驗證成功,放行");filterChain.doFilter(servletRequest, servletResponse);
?此時再通過url訪問后,查看控制臺的信息可以看到:
?5.攔截方式配置(資源被訪問方式)
當然除了路徑訪問可以攔截以外,還可以設置攔截的方式,有些請求可以直接輸入url直接訪問類。有些通過一些網頁實現跳轉的方式獲取類的資源。還有就是通過請求轉發的形式獲取類。所以基于如此可以對這些方法做一些限制。
攔截方法 | 描述 |
---|---|
REQUEST(請求攔截) | 攔截直接通過 URL 訪問的請求。 |
FOWARD(轉發攔截) | 攔截通過請求轉發方式獲取資源的請求。 |
INCLUDE(包含攔截) | 攔截通過網頁跳轉方式獲取資源的請求。 |
ERROR(錯誤攔截) | 攔截發生錯誤或異常情況的請求。 |
ASYNC(異步攔截) | 攔截異步請求,即延遲加載的請求,可以防止對響應進行預先緩存和使用。 |
默認情況下是通過REQUEST實現攔截
具體使用還需要看開始時候使用的配置
- 通過xml配置
<filter><filter-name>filterDemo1</filter-name><filter-class>com.company.Filter.filterDemo1</filter-class></filter><filter-mapping><filter-name>filterDemo1</filter-name><url-pattern>/*</url-pattern>
<!-- 配置請求攔截方法--><dispatcher>REQUEST</dispatcher></filter-mapping>
- 通過注解類配置
6.FilterChain攔截鏈
攔截鏈,顧名思義就是由多個過濾器組成,就像是一條路設置了多個收費站一樣。只有滿足所有的攔截規則后才能通過。
設置多個攔截器(其中一個的代碼)
package com.company.Filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter("/*")
public class filterDemo3 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("攔截器1進行攔截");System.out.println("攔截器1放行");
// 攔截器放行filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}
通過url訪問時候結果如下
?攔截器的順序
一.注解配置
是通過攔截器名字的排序比如01、02、03,先比較第一個數字大小,如果相同就比較第二個數字大小以此類推
二.xml配置
只需要配置xml時候由上往下即可
?