天天看點

Filter過濾器1. 引言2. Filter API3. Filter配置4. 示例程式

文章目錄

  • 1. 引言
  • 2. Filter API
    • 2.1 Filter接口
  • 3. Filter配置
  • 4. 示例程式

1. 引言

Filter是過濾Request請求的對象,在使用者的請求通路資源前處理ServletRequest以及ServletResponse,他可用于日志記錄、加解密、Session檢查、圖像檔案保護等。Filter配置可以通過注解或者部署描述來完成,當需要多個Filter配合并強調順序時隻能通過部署描述符配置。

2. Filter API

Filter相關接口包括Filter、FilterConfig、FilterChain,Filter實作必須繼承javax.servlet.Filter接口。

2.1 Filter接口

包含三個生命周期init、doFilter、destroy,servlet容器初始化Filter時,會觸發Filter的init方法,FilterConfig執行個體由Servlet容器傳入init方法中。

void init(FilterConfig filterConfig)
           

Servlet容器每次處理Filter相關資源時,會調用相關Filter執行個體的doFilter方法

void doFilter(ServletRequest request, Servlet Response, FilterChanin filterChain)
           

在Filter的doFilter的實作中,最後一行需要調用FilterChain中的doFilter方法

filterChain.doFilter(ServletRequest request, ServletResponse response)
           

一個資源可能被多個Filter關聯到(Filter鍊條),這時Filter.doFilter()方法将觸發Filter鍊條中下一個Filter。隻有在Filter鍊條中的最後一個Filter裡調用FilterChain.doFilter()才會觸發處理資源方法,否則Request請求終止。 FilterChain接口隻定義了一個方法doFilter用于Filter鍊條

public interface FilterChain {
	
	/**
	* Causes the next filter in the chain to be invoked, or if the calling filter is the last filter
	* in the chain, causes the resource at the end of the chain to be invoked.
	*
	* @param request the request to pass along the chain.
	* @param response the response to pass along the chain.
	*/
	
    public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;

}
           

Filter接口最後一個方法是destroy,在servlet容器要銷毀Filter時觸發

void destroy();
           

3. Filter配置

Filter配置需要如下步驟:

  1. 确認哪些資源需要使用這個Filter攔截器
  2. 配置Filter的初始化參數值
  3. 給Filter取一個名稱,友善識别

FilterConfig接口允許通過他的getServletContext方法通路ServletContext

ServletContext getServletContext();                             //傳回ServletContext
java.lang.String getFilterName();                               //傳回Filter名字
java.util.Enumeration<java.lang.String> getInitParameterNames() //傳回初始化參數名
java.lang.String getInitParameter(java.lang.String parameterName)//傳回參數
           

配置方式有兩種,一種是@WebFilter注解方法,另一種是通過XML注冊方式,以@WebFilter注解為例,下面是可選參數

屬性 描述
asyncSupported Filter是否支援異步操作
description Filter描述
dispatcherTypes Filter生效範圍
displayName Filter顯示名
filterName Filter名稱
initParams Filter初始化參數
urlPatterns Filter生效的URL路徑
value Filter生效的URL路徑
@WebFilter(filterName = "Security Filter", urlPatterns = "/*",
  initParams = {
    @WebInitParam(name = "A", value = "1")
    @WebInitParam(name = "B", value = "2")
  })
           

4. 示例程式

package config.filter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

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.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;

/**
 * 日志監聽器,記錄每天的通路情況
 * @author littlemotor
 * @since 18.8.22
 */
@WebFilter(filterName = "LoggingFilter",
           urlPatterns = {"/*"},
           initParams = {
             @WebInitParam(name = "logFileName", value = "log.txt")
           })
public class LoggingFilter implements Filter{

  private PrintWriter viewLogger;
  private PrintWriter counterLogger;
  
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    //String logFileName = filterConfig.getInitParameter("logFileName");
    //String appPath = filterConfig.getServletContext().getRealPath("/");
    //System.out.println(appPath);
    try {
      viewLogger = new PrintWriter(new File("/Users/littlemotor/webLog/","log.txt"));
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
  }

  /**
   * Filter鍊,注意在最後加doFilter
   */
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest)request;
    viewLogger.println(new Date() + " " + "URI: " + httpRequest.getRequestURI() );
    viewLogger.flush();  
    chain.doFilter(request, response);
  }

  @Override
  public void destroy() {
    System.out.println("destroying filter");
    if(viewLogger != null) {
      viewLogger.close();
    }
  }
}
           

繼續閱讀