寫在前面: 今天我來簡單的介紹一下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技術,開發人員可以實現用戶在訪問某個目標資源之前,對訪問的請求和響應進行攔截,如下所示:
攔截請求常見的應用場景有:
1、權限檢查
2、日記操作
3、事務管理
……等等
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原理:
Filter 過濾器的使用步驟:
1、編寫一個類去實現Filter 接口
2、實現過濾方法doFilter()
3、到web.xml 中去配置Filter 的攔截路徑
練習:Filter登陸過濾:
要求: 在這個頁面,點跳轉到一個頁面中,實現需要登陸成功後才能夠跳轉
需要登陸才能跳轉這個頁面
思路: 在登陸的時候,向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頁面,
我們來看看Debug,是因爲給我的Filter過濾器攔截了,user是null,請求轉發回登陸頁面了
當我登陸後:向Session域中設置了一個user對象,此時登陸成功:
Debug中可以看出,我在登陸成功的時候,向Session域中放入了user對象
所以再次返回首頁,我再次點擊跳轉頁面:
此時Debug中,發現Filter檢測到了Session中有一個user對象,並且通過dofiler放行了頁面。所以我們能夠進入success.html頁面
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 就是過濾器鏈(多個過濾器如何一起工作)
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的簡單介紹內容。若有問題可以私聊我。