Java Filter過濾器的簡單總結


1.Filter的介紹

Filter技術是servlet 2.3新增加的功能。它能夠對Servlet容器的請求和響應對象進行檢查和修改。

Filter本身並不生成請求和響應對象,只是提供過濾功能。

Filter能夠在Servlet被調用之前檢查Request對象,並修改Request Header和Request內容;在Servlet被調用之后檢查Response對象,修改Response Header和Response的內容。

Filter可以過濾的Web組件包括Servlet,JSP和HTML等文件。

2.Filter的工作原理

        當客戶端發出Web資源的請求時,Web服務器根據應用程序配置文件設置的過濾規則進行檢查,若客戶請求滿足過濾規則,則對客戶請求/響應進行攔截,對請求頭和請求數據進行檢查或改動,並依次通過過濾器鏈,最后把請求/響應交給請求的Web資源處理。請求信息在過濾器鏈中可以被修改,也可以根據條件讓請求不發往資源處理器,並直接向客戶機發回一個響應。當資源處理器完成了對資源的處理后,響應信息將逐級逆向返回。同樣在這個過程中,用戶可以修改響應信息,從而完成一定的任務。

        兩個過濾器同時過濾一個請求時,就要用到過濾鏈FilterChainFilterFilterChain中,服務器會按照web.xml中過濾器定義的先后循序組裝成一條鏈,然后一次執行其中的doFilter()方法。執行的順序就如下圖所示,執行第一個過濾器的chain.doFilter()之前的代碼,第二個過濾器的chain.doFilter()之前的代碼,請求的資源,第二個過濾器的chain.doFilter()之后的代碼,第一個過濾器的chain.doFilter()之后的代碼,最后返回響應。

 

        Filter的執行流程就是:執行第一個過濾器的chain.doFilter()之前的代碼——>第二個過濾器的chain.doFilter()之前的代碼——>……——>n個過濾器的chain.doFilter()之前的代碼——>所請求servletservice()方法中的代碼——>所請求servletdoGet()doPost()方法中的代碼——>n個過濾器的chain.doFilter()之后的代碼——>……——>第二個過濾器的chain.doFilter()之后的代碼——>第一個過濾器的chain.doFilter()之后的代碼。

3.Filter生命周期的四個階段

(1)實例化:Web容器在部署Web應用程序時對所有過濾器進行實例化。Web容器回調它的無參構造方法。

(2)初始化:實例化完成之后,馬上進行初始化工作。Web容器回調init()方法。

(3)過濾:請求路徑匹配過濾器的URL映射時。Web容器回調doFilter()方法——主要的工作方法。

(4)銷毀: Web容器在卸載Web應用程序前,Web容器回調destroy()方法。

4.Filter的API

public Interface Filter
所有的過濾器都必須實現Filter接口。該接口定義了init,doFilter0,destory()三個方法:


  (1) public void init (FilterConfig filterConfig) 
當開始使用servlet過濾器服務時,Web容器調用此方法一次,為服務准備過濾器;然后在需要使用過濾器的時候調用doFilter(),傳送給此方法的FilterConfig對象,包含servlet過濾器的初始化參數。

示例:

Filter的init方法中提供了一個FilterConfig對象,提供相關的操作:

如獲取Filter中配置的初始化參數:
<filter>
      <filter-name>LoginFilter</filter-name>
      <filter-class>com.itzhai.login.LoginFilter</filter-class>
      <init-param>
          <param-name>username</param-name>
          <param-value>HelloWorld</param-value>
      </init-param>
</filter>

在init方法中獲取:

 
@Override
public void init(FilterConfig filterConfig) throws ServletException
 {
    //獲取Filter初始化參數
    String username = filterConfig.getInitParameter("username");
}

 

  (2)public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)    
         每個過濾器都接受當前的請求和響應,且FilterChain過濾器鏈中的過濾器(應該都是符合條件的)都會被執行。doFilter方 法中,過濾器可以對請求和響應做它想做的一切,通過調用他們的方法收集數據,或者給對象添加新的行為。過濾器通過傳送至 此方法的FilterChain參數,調用chain.doFilterO將控制權傳送給下一個過濾器。當這個調用返回后,過濾器可以在它的 Filter方法的最后對響應做些其他的工作。如果過濾器想要終止請求的處理或得到對響應的完全控制,則可以不調用下一個過濾 器,而將其重定向至其它一些頁面。當鏈中的最后一個過濾器調用chain.doFilterO方法時,將運行最初請求的Servlet。

 

 (3)public void destroy()
       一旦doFilterO方法里的所有線程退出或已超時,容器調用此方法。服務器調用destoryO以指出過濾器已結束服務,用於釋放過濾器占用的資源。

5.例子

過濾敏感詞匯

package com.zhouyu.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FilterTest implements Filter
{

	@Override
	public void destroy()
	{
		// TODO Auto-generated method stub
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
	{
		// 轉換成實例的請求和響應對象
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		// 獲取評論並屏蔽關鍵字
		String str = req.getParameter("str");
		str = str.replace("你妹呀", "***");
		// 重新設置參數
		req.setAttribute("str", str);
		// 繼續執行
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException
	{
		// TODO Auto-generated method stub

	}
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM