Servlet - 編寫過濾器



Servlet 過濾器是可以在 Servlet 程式設計中用於以下目的的 Java 類:

  • 在客戶端訪問後端資源之前攔截來自客戶端的請求。

  • 在伺服器將響應傳送回客戶端之前操作伺服器的響應。

規範建議了各種型別的過濾器:

  • 身份驗證過濾器。
  • 資料壓縮過濾器。
  • 加密過濾器。
  • 觸發資源訪問事件的過濾器。
  • 影像轉換過濾器。
  • 日誌記錄和審計過濾器。
  • MIME 型別鏈過濾器。
  • 標記化過濾器。
  • 轉換 XML 內容的 XSL/T 過濾器。

過濾器部署在部署描述符檔案web.xml中,然後對映到應用程式部署描述符中的 Servlet 名稱或 URL 模式。

當 Web 容器啟動您的 Web 應用程式時,它會建立您在部署描述符中宣告的每個過濾器的例項。過濾器按其在部署描述符中宣告的順序執行。

Servlet 過濾器方法

過濾器只是一個實現了 javax.servlet.Filter 介面的 Java 類。javax.servlet.Filter 介面定義了三個方法:

序號 方法和描述
1

public void doFilter (ServletRequest, ServletResponse, FilterChain)

每次由於客戶端對鏈末端資源的請求而導致請求/響應對透過鏈傳遞時,容器都會呼叫此方法。

2

public void init(FilterConfig filterConfig)

Web 容器呼叫此方法以指示過濾器已投入服務。

3

public void destroy()

Web 容器呼叫此方法以指示過濾器即將停止服務。

Servlet 過濾器 - 示例

以下是一個 Servlet 過濾器示例,它將列印客戶端的 IP 地址和當前日期時間。此示例將為您提供對 Servlet 過濾器的基本瞭解,但您可以使用相同的概念編寫更復雜的過濾器應用程式:

// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

// Implements Filter class
public class LogFilter implements Filter  {
   public void  init(FilterConfig config) throws ServletException {
      
      // Get init parameter 
      String testParam = config.getInitParameter("test-param"); 

      //Print the init parameter 
      System.out.println("Test Param: " + testParam); 
   }
   
   public void  doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws java.io.IOException, ServletException {

      // Get the IP address of client machine.
      String ipAddress = request.getRemoteAddr();

      // Log the IP address and current timestamp.
      System.out.println("IP "+ ipAddress + ", Time " + new Date().toString());

      // Pass request back down the filter chain
      chain.doFilter(request,response);
   }

   public void destroy( ) {
      /* Called before the Filter instance is removed from service by the web container*/
   }
}

以通常的方式編譯LogFilter.java,並將您的類檔案放在<Tomcat 安裝目錄>/webapps/ROOT/WEB-INF/classes中

Web.xml 中的 Servlet 過濾器對映

過濾器定義後,會對映到 URL 或 Servlet,這與 Servlet 定義後對映到 URL 模式的方式非常相似。在部署描述符檔案web.xml中建立以下過濾器標籤條目:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>LogFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

由於我們在配置中指定了/*,因此上述過濾器將應用於所有 Servlet。如果只想將過濾器應用於少數 Servlet,則可以指定特定的 Servlet 路徑。

現在嘗試以通常的方式呼叫任何 Servlet,您將在 Web 伺服器日誌中看到生成的日誌。您可以使用 Log4J 記錄器將上述日誌記錄到單獨的檔案中。

使用多個過濾器

您的 Web 應用程式可能會定義幾個具有特定用途的不同過濾器。假設您定義了兩個過濾器AuthenFilterLogFilter。其餘過程將與上面解釋的相同,除了您需要建立如下所示的不同對映:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>LogFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter>
   <filter-name>AuthenFilter</filter-name>
   <filter-class>AuthenFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

過濾器應用順序

web.xml 中 filter-mapping 元素的順序決定了 Web 容器將過濾器應用於 Servlet 的順序。要反轉過濾器的順序,您只需反轉 web.xml 檔案中的 filter-mapping 元素即可。

例如,上面的示例將首先應用 LogFilter,然後將其應用於任何 Servlet,但以下示例將反轉順序:

<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
廣告