1. 程式人生 > 實用技巧 >【JavaWeb】Filter 過濾器

【JavaWeb】Filter 過濾器

Filter 過濾器

簡介

  • Filter 過濾器是 JavaWeb 三大元件之一
  • Filter 過濾器是 JavaEE 的規範,也就是介面
  • Filter 過濾器的作用是 攔截請求,過濾響應

攔截請求的常見應用場景:

  • 許可權檢查
  • 日誌操作
  • 事務管理

使用步驟

使用步驟

  • 編寫一個類去實現 Filter 介面
  • 實現過濾方法 doFilter()
  • 到 web.xml中配置 Filter 的攔截路徑,或者用註解配置

Filter 的工作流程圖:

使用例項

實現一個完整的使用者登入

login.jsp 頁面,登入表單:

這是登入頁面。login.jsp 頁面 <br>
<form action="http://localhost:8080/15_filter/loginServlet" method="get">
    使用者名稱:<input type="text" name="username"/> <br>
    密 碼:<input type="password" name="password"/> <br>
    <input type="submit" />
</form>

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 ("parzulpan".equals(username) && "123456".equals(password)) {
        req.getSession().setAttribute("user",username);
        resp.getWriter().write("登入 成功!!!");
    } else {
        req.getRequestDispatcher("/login.jsp").forward(req,resp);
    }
    }
}

AdminFilter 過濾器:

package cn.parzulpan.web;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Author : parzulpan
 * @Time : 2020-12-13
 * @Desc :
 */

public class AdminFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    // doFilter 方法,專門用於攔截請求,可以做許可權檢查
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object user = session.getAttribute("user");
        // 如果等於 null,說明還沒有登入
        if (user == null) {
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
            return;
        } else {
        // 讓程式繼續往下訪問使用者的目標資源
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

web.xml 中的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

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

生命週期

Filter 的生命週期包含幾個方法:

  • 第 1 步,構造器方法
  • 第 2 步,init 初始化方法
    • 第 1,2 步,在 web 工程啟動的時候執行(Filter 已經建立)
  • 第 3 步,doFilter 過濾方法
    • 第 3 步,每次攔截到請求就會執行
  • 第 4 步,destory 銷燬方法
    • 第 4 步,停止 web 工程的時候就會執行(停止 web 工程也會銷燬 Filter 過濾器)

FilterConfig 類

FilterConfig 類是 Filter 過濾器的配置檔案類,Tomcat 每次建立 Filter 的時候,也會同時建立一個 FilterConfig 類,它包含了 Filte 配置檔案的配置資訊。

FilterConfig 類的作用是獲取 Filter 過濾器的配置內容:

  • filterConfig.getFilterName() 獲取 Filter 的名稱 Filter-name 的內容
  • filterConfig.getInitParameter(String param) 獲取在 Filter 中配置的 init-param 初始化引數
  • filterConfig.getServletContext() 獲取 ServletContext 物件

FilterChain 過濾器鏈

Filter 是過濾器,Chain 是鏈條,FilterChain 就是過濾器鏈,指多個過濾器一起工作。

FilteChain.doFilter() 的使用:

  • 如果有 Filter,則執行下一個 Filter 過濾器
  • 如果沒有 Filter,則執行目標資源
  • 有 多個 Filter 的情況下,它們的執行的優先順序是由 web.xml 中從上到下配置的順序決定

多個 Filter 執行的特點:

  • 所有的 Filter 和目標資源預設都執行在同一個執行緒下
  • 多個 Filter 共同執行的時候,它們都是使用同一個 Request 物件

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 過濾器只關心請求的地址是否被匹配,不關心請求的資源是否存在。

總結和練習