一、用途
對web的請求或響應進行攔截并做一些業務邏輯判斷和處理。
例如:可以使用過濾器攔截一個request來做一些預處理,然後再交給下一個過濾器或servlet進一步處理(也可以對傳回的response進行攔截過濾)。
應用場景:
1.身份驗證
2.記錄和稽核
3.圖像轉換
4.資料壓縮
5.加密
6....
二、工作原理
流程圖
過濾器是随着web應用的啟動而啟動的,隻會初始化一次,之後便可以攔截過濾相關的請求或響應,當web應用停止或重新部署的時候才會被銷毀。
下面我們通過代碼示例來學習如何使用它。
三、上代碼
Filter接口源碼:
package javax.servlet;
import java.io.IOException;
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
可以看到,在Filter接口中定義了一個doFilter方法,該方法正是過濾器執行過濾動作的方法;
每個過濾器都有權通路filterConfig對象,并從中擷取初始化參數;
當我們編寫好Filter的實作類,并在web應用程式的部署描述符「web.xml」中配置好需要攔截過濾的web資源後,web伺服器就會在調用web資源的service方法之前先調用這個doFilter方法 。
此時你就可以針對需要攔截過濾的web資源(Request、Response)進行業務邏輯判斷和處理,進而簡化操作。
例如:統一設定字元編碼、判斷使用者是否已經登陸、判斷有沒有權限通路頁面等...
Filter的開發主要分為2步:
1.編寫java類,實作Filter接口及其方法
package com.ys.test;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.Enumeration;
@WebFilter(filterName = "TestFilter")
public class TestFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
System.out.println("TestFilter初始化...");
Enumeration paramNames = config.getInitParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String paramValue = config.getInitParameter(paramName);
System.out.println(paramName + "=" + paramValue);
}
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
System.out.println("TestFilter被執行...");
// 針對req和resp統一設定字元編碼
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 放行,順着過濾鍊繼續往下走,若下一個目标仍是Filter,則執行該Filter的doFilter方法
// 若下一個目标是Servlet,則調用Servlet的service方法
chain.doFilter(req, resp);
}
public void destroy() {
System.out.println("TestFilter被銷毀!");
}
}
2.配置需要攔截過濾的web資源
在web.xml 檔案中使用和元素對編寫的Filter實作類進行注冊,并設定它所能攔截的web資源
統一字元編碼過濾器
characterEncodingFilter
com.ys.test.TestFilter
初始化參數1
encoding1
GBK
初始化參數2
encoding2
UTF-8
characterEncodingFilter
*.do
REQUEST
FORWARD
INCLUDE
ERROR
ASYNC
也可以直接在Filter的實作類中使用@WebFilter注解來注冊
@WebFilter(filterName = "TestFilter",
// 配置初始化參數
initParams = {@WebInitParam(name = "encoding1", value = "GBK"), @WebInitParam(name = "encoding2", value = "UTF-8")},
// 配置要攔截的資源
urlPatterns = "*.do",
// 配置攔截的類型
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR, DispatcherType.ASYNC})
public class TestFilter implements Filter {
...
四、攔截方式配置
攔截方式配置也就是指定過濾器的排程模式,主要有下面幾種:
REQUEST
預設值,浏覽器直接請求資源。
FORWARD
轉發通路資源:RequestDispatcher.forward();
如果目标資源是通過RequestDispatcher的forward()方法通路時,那麼該過濾器将被調用。
INCLUDE
包含通路資源:RequestDispatcher.include();
如果目标資源是通過RequestDispatcher的include()方法通路時,那麼該過濾器将被調用。
ERROR
錯誤跳轉資源:被聲明式異常處理機制調用的時候;
如果目标資源是通過聲明式異常處理機制調用時,那麼過濾器被将被調用。
ASYNC(Servlet3.0新增加)
支援異步處理