【JavaWeb】Filter 過濾器
阿新 • • 發佈:2020-12-14
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 過濾器只關心請求的地址是否被匹配,不關心請求的資源是否存在。