學習web必學的三大組件之Filter過濾器

寫在前面: 今天我來簡單的介紹一下Filter過濾器,希望對小白有所幫助。
作者公衆號:小白編碼
前一篇介紹了: 乾貨來了!JavaWeb三大組件之Servlet核心技術,附帶Http協議【較全整理】

Filter 什麼是過濾器

1、Filter 過濾器它是JavaWeb 的三大組件之一。三大組件分別是:Servlet 程序、Listener 監聽器、Filter 過濾器
2、Filter 過濾器它是JavaEE 的規範。也就是接口
3、Filter 過濾器它的作用是:攔截請求,過濾響應。

Filter 的基本功能是 Servlet 容器調用 Servlet 的過程進行攔截從而在 Servlet 進行響應處理的前後實現一些特殊的功能

在 Servlet API 中定義了三個接口類來開供開發人員編寫 Filter 程序:Filter, FilterChain, FilterConfig

Filter 程序是一個實現了 Filter 接口的 Java ,與 Servlet 程序相似,它由 Servlet 容器進行調用和執行

Filter 程序需要在 web.xml 文件中進行註冊和設置它所能攔截的資源:Filter 程序可以攔截 Jsp, Servlet, 靜態圖片文件和靜態 html 文件

一、Filter簡介

Filter也稱之爲過濾器,它是Servlet技術中最激動人心的技術,WEB開發人員通過Filter技術,對web服務器管理的所有web資源:例如Jsp, Servlet, 靜態圖片文件或靜態 html 文件等進行攔截,從而實現一些特殊的功能。例如實現URL級別的權限訪問控制、過濾敏感詞彙、壓縮響應信息等一些高級功能。
  Servlet API中提供了一個Filter接口,開發web應用時,如果編寫的Java類實現了這個接口,則把這個java類稱之爲過濾器Filter。通過Filter技術,開發人員可以實現用戶在訪問某個目標資源之前,對訪問的請求和響應進行攔截,如下所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AC91WFWJ-1589384811933)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200510102654044.png)]

攔截請求常見的應用場景有:
1、權限檢查
2、日記操作
3、事務管理
……等等

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-X9yw9D2Y-1589384811936)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513115314876.png)]

Filter使用

FilterChain接口:代表當前 Filter 鏈的對象。由容器實現,容器將其實例作爲參數傳入過濾器對象的doFilter()方法中。過濾器對象使用FilterChain 對象調用過濾器鏈中的下一個過濾器,如果該過濾器是鏈中最後一個過濾器,那麼將調用目標資源。

doFilter(ServletRequest request,ServletResponse response)throws java.io.IOException:調用該方法將使過濾器鏈中的下一個過濾器被調用。如果是最後一個過濾器,會調用目標資源。

FilterConfig接口

javax.servlet.FilterConfig接口:該接口類似於ServletConfig接口,由容器實現。**Servlet ** 規範將代表 ServletContext 對象和 Filter **的配置參數信息都封裝在該對象中。**Servlet 容器將其作爲參數傳入過濾器對象的init()方法中。

String getFilterName():得到描述符中指定的過濾器的名字。

String getInitParameter(String name): 返回在部署描述中指定的名字爲name的初始化參數的值。如果不存在返回null.

Enumeration getInitParameterNames():返回過濾器的所有初始化參數的名字的枚舉集合。

public ServletContext getServletContext():返回Servlet上下文對象的引用。

Filter原理:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-viIlafBz-1589384811937)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200508175403215.png)]

Filter 過濾器的使用步驟:

1、編寫一個類去實現Filter 接口
2、實現過濾方法doFilter()
3、到web.xml 中去配置Filter 的攔截路徑

練習:Filter登陸過濾:

要求: 在這個頁面,點跳轉到一個頁面中,實現需要登陸成功後才能夠跳轉

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TLnHCinx-1589384811939)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513232251222.png)]

需要登陸才能跳轉這個頁面

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WWYoIS02-1589384811940)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513232339582.png)]

思路: 在登陸的時候,向Session域中設置一個user對象,通過判斷Session中的user來確定用戶是否登陸。

index.jsp :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <base href="http://localhost:8080/filter/">
  <body>
  <form action="http://localhost:8080/filter/loginServlet" method="get">
    用戶名:<input type="text" name="username"/> <br>
    密碼:<input type="password" name="password"/> <br>
    <input type="submit" />
  </form><br/>
  <a href="success.html">跳轉一個頁面</a>
  </body>
</html>

LoginServlet:

public class LoginServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //響應亂碼,設置編碼集
        resp.setContentType("text/html; charset=UTF-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if ("admin".equals(username) && "admin".equals(password)) {
            //向session域中放入user對象,用於dofilter判斷
            req.getSession().setAttribute("user", username);
            resp.getWriter().write("登錄成功!!!");
        } else {
            req.getRequestDispatcher("/index.jsp").forward(req, resp);
        }
    }
}

LoginFilter:

public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
		//獲取session中的user
        Object user = req.getSession().getAttribute("user");

        if (user == null) {
            //如果沒有登陸
            //請求轉發回登陸頁面
            req.getRequestDispatcher("index.jsp").forward(servletRequest, servletResponse);
        } else {
            //放行
            filterChain.doFilter(servletRequest, servletResponse);

        }
}

success.Html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>這是登陸後才能訪問的頁面</h1><br/>
<a href="index.jsp">回到登陸頁面</a>
</body>
</html>

XML:

  <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>cn.codewhite.filter.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>

   
    <!--filter 標籤用於配置一個Filter 過濾器-->
    <filter>
        <!--給filter 起一個別名-->
        <filter-name>LoginFilter</filter-name>
        <!--配置filter 的全類名-->
        <filter-class>cn.codewhite.filter.LoginFilter</filter-class>
    </filter>
    <!--filter-mapping 配置Filter 過濾器的攔截路徑-->
    <filter-mapping>
        <!--filter-name 表示當前的攔截路徑給哪個filter 使用-->
        <filter-name>LoginFilter</filter-name>
        <!--url-pattern 配置攔截路徑
       / 表示請求地址爲:http://ip:port/工程路徑/ 映射到IDEA 的web 目錄
       /success.html 表示請求地址爲:http://ip:port/工程路徑/success.html
       -->
        <url-pattern>/success.html</url-pattern>
    </filter-mapping>

測試結果:

此時,我並沒有登陸,點擊跳轉一個頁面,地址欄發生改變了,大門但是並沒有跳轉到success.html頁面,

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FAlL1I6r-1589384811942)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513234107606.png)]

我們來看看Debug,是因爲給我的Filter過濾器攔截了user是null,請求轉發回登陸頁面了

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HcI7F8Y2-1589384811943)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513234057850.png)]

當我登陸後:向Session域中設置了一個user對象,此時登陸成功:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-R21iVoqQ-1589384811944)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513234401221.png)]

Debug中可以看出,我在登陸成功的時候,向Session域中放入了user對象

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-609wTc23-1589384811944)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513234312671.png)]

所以再次返回首頁,我再次點擊跳轉頁面:

此時Debug中,發現Filter檢測到了Session中有一個user對象,並且通過dofiler放行了頁面。所以我們能夠進入success.html頁面

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-05N9fngj-1589384811945)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513234520616.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-F0jXVPTb-1589384811946)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200513234621590.png)]

Filter 的生命週期

Filter 的生命週期包含幾個方法:
1、構造器方法
2、init 初始化方法
第1,2 步,在web 工程啓動的時候執行(Filter 已經創建)
3、doFilter 過濾方法
第3 步,每次攔截到請求,就會執行
4、destroy 銷燬
第4 步,停止web 工程的時候,就會執行(停止web 工程,也會銷燬 Filter 過濾器)

FilterConfig 類

FilterConfig 類見名知義,它是Filter 過濾器的配置文件類。
Tomcat 每次創建Filter 的時候,也會同時創建一個FilterConfig 類,這裏包含了Filter 配置文件的配置信息。

FilterConfig 類的作用是獲取filter 過濾器的配置內容
1、獲取Filter 的名稱filter-name 的內容
2、獲取在Filter 中配置的init-param 初始化參數
3、獲取ServletContext 對象

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("2.Filter 的init(FilterConfig filterConfig)初始化");
    // 1、獲取Filter 的名稱filter-name 的內容
    System.out.println("filter-name 的值是:" + filterConfig.getFilterName());
    // 2、獲取在web.xml 中配置的init-param 初始化參數
    System.out.println("初始化參數username 的值是:" + filterConfig.getInitParameter("username"));
    System.out.println("初始化參數url 的值是:" + filterConfig.getInitParameter("url"));
    // 3、獲取ServletContext 對象
    System.out.println(filterConfig.getServletContext());
}

xml:

<!--filter 標籤用於配置一個Filter 過濾器-->
<filter>
<!--給filter 起一個別名-->
<filter-name>AdminFilter</filter-name>
<!--配置filter 的全類名-->
<filter-class>com.atguigu.filter.AdminFilter</filter-class>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost3306/test</param-value>
</init-param>
</filter>

FilterChain 過濾器鏈

Filter 過濾器
Chain 鏈,鏈條
FilterChain 就是過濾器鏈(多個過濾器如何一起工作)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cXM2hg4m-1589384811946)(C:\Users\JUN\AppData\Roaming\Typora\typora-user-images\image-20200508180049851.png)]

Filter 的攔截路徑:

–精確匹配

<url-pattern>/target.jsp</url-pattern>

以上配置的路徑,表示請求地址必須爲:http://ip:port/工程路徑/target.jsp

–目錄匹配

<url-pattern>/admin/* </url-pattern>

以上配置的路徑,表示請求地址必須爲:http://ip:port/工程路徑/admin/*

–後綴名匹配

<url-pattern> * .html</url-pattern>

以上配置的路徑,表示請求地址必須以.html 結尾纔會攔截到

<url-pattern>* .do</url-pattern>

以上配置的路徑,表示請求地址必須以.do 結尾纔會攔截到

<url-pattern>*.action</url-pattern>

以上配置的路徑,表示請求地址必須以.action 結尾纔會攔截到
Filter 過濾器它只關心請求的地址是否匹配,不關心請求的資源是否存在!!!

寫在後邊:

以上就是JavaWeb三大組件之Filter的簡單介紹內容。若有問題可以私聊我。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章