天天看點

java 過濾器_Java過濾器(Filter)

一、用途

對web的請求或響應進行攔截并做一些業務邏輯判斷和處理。

例如:可以使用過濾器攔截一個request來做一些預處理,然後再交給下一個過濾器或servlet進一步處理(也可以對傳回的response進行攔截過濾)。

應用場景:

1.身份驗證

2.記錄和稽核

3.圖像轉換

4.資料壓縮

5.加密

6....

二、工作原理

java 過濾器_Java過濾器(Filter)

流程圖

過濾器是随着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新增加)

支援異步處理