English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

ServletFilter schreiben

Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。

可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet。Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。

Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:

  • 在客户端的请求访问后端资源之前,拦截这些请求。

  • 在服务器的响应发送回客户端之前,处理这些响应。

根据规范建议的各种类型的过滤器:

  • Authentication Filters).

  • Data compression Filters).

  • Encryption Filters).

  • Trigger resource access event filters.

  • Image Conversion Filters).

  • Logging and Auditing Filters).

  • MIME-TYPE MIME Chain Filters).-TYPE Chain Filters).

  • Tokenizing Filters).

  • XSL/T Filter (XSL/T Filters), XML-Inhalte konvertieren.

Filter werden durch die XML-Tags im Web Deployment Descriptor (web.xml) deklariert und dann auf den Servlet-Namen oder das URL-Muster in der Deployment-Deklaration Ihres Anwendungsmaps gelinkt.

Wenn der Web-Container die Web-Anwendung startet, erstellt er für jeden Filter, den Sie in der Deployment-Deklaration angegeben haben, ein Beispielobjekt.

Die Ausführungsreihenfolge der Filter ist mit der Reihenfolge der Konfiguration in der Datei web.xml übereinstimmend. Normalerweise wird der Filter vor allen Servlets konfiguriert.

Servlet Filter Methoden

Ein Filter ist eine Java-Klasse, die das Interface javax.servlet.Filter implementiert. Das javax.servlet.Filter-Interface definiert drei Methoden:

NummerMethode & Beschreibung
1public void doFilter(ServletRequest, ServletResponse, FilterChain)
Diese Methode führt die tatsächliche Filterung durch. Wenn die Anfrage des Clients mit der URL des Filters übereinstimmt, ruft der Servlet-Container zunächst die doFilter-Methode des Filters auf. Der FilterChain ermöglicht den Zugriff auf nachfolgende Filter.
2public void init(FilterConfig filterConfig)
Bei der Initialisierung der Web-Anwendung erstellt der Web-Server ein Beispielobjekt des Filters und ruft dessen init-Methode auf, um die Konfiguration aus web.xml zu lesen und die Initialisierungsfunktion des Objekts abzuschließen. Dies bereitet die Interceptionsvorbereitungen für nachfolgende Benutzeranfragen vor (der Filter-Objekt wird nur einmal erstellt, und die init-Methode wird nur einmal ausgeführt). Entwickler können über die Parameter der init-Methode das FilterConfig-Objekt erhalten, das die aktuelle Filterkonfigurationsinformation repräsentiert.
3public void destroy()
Servlet 容器在销毁过滤器示例前调用该方法,在该方法中释放 Servlet 过滤器占用的资源。

FilterConfig 使用

Filter 的 init 方法中提供了一个 FilterConfig 对象。

如 web.xml 文件配置如下:

<filter>
    <filter-name>LogFilter</filter-name>
    <filter-class>com.w3codebox.test.LogFilter</filter-class>
    <init-param>
        <param-name>Site</param-name>
        <param-value>Grund教程网</param-value>
    </init-param>
</filter>

在 init 方法使用 FilterConfig 对象获取参数:

public void init(FilterConfig config) throws ServletException {
    // 获取初始化参数
    String site = config.getInitParameter("Site"); 
    // 输出初始化参数
    System.out.println("网站名称: " + site); 
}

Servlet 过滤器示例

以下是 Servlet 过滤器的示例,将输出网站名称和地址。本示例让您对 Servlet 过滤器有基本的了解,您可以使用相同的概念编写更复杂的过滤器应用程序:

package com.w3codebox.test;
//导入必需的 java 库
import javax.servlet.*;
import java.util.*;
//实现 Filter 类
public class LogFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
        // 获取初始化参数
        String site = config.getInitParameter("Site"); 
        // 输出初始化参数
        System.out.println("网站名称: " + site); 
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
        // 输出站点名称
        System.out.println("站点网址:http://de.oldtoolbag.com");
        // 把请求传回过滤链
        chain.doFilter(request,response);
    }
    public void destroy( ){
        /* 在 Filter 示例被 Web 容器从服务移除之前调用 */
    }
}

这边使用前文提到的 DisplayHeader.java 为实例:

//导入必需的 java 库
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DisplayHeader")
//扩展 HttpServlet 类
public class DisplayHeader extends HttpServlet
    // 处理 GET 方法请求的方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String title = "HTTP Header Anfragebeispiel - 基础教程网示例";
        String docType =
            "<!DOCTYPE html> \n";
            out.println(docType +
            "<html>\n" +
            "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+
            "<body bgcolor=\"#f0f0f0\">\n" +
            "<h1 align=\"center\">" + title + "</h1>\n" +
            "<table width=\"100%\" border=\"1\" align=\"center\">\n" +
            "<tr bgcolor=\"#949494\">\n" +
            "<th>Header Name</th><th>Header Wert</th>\n"+
            "</tr>\n");
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {}}
            String paramName = (String)headerNames.nextElement();
            out.print("<tr><td>" + paramName + "</td>\n");
            String paramValue = request.getHeader(paramName);
            out.println("<td> " + paramValue + "</td></tr>\n");
        }
        out.println("</table>\n</body></html>");
    }
    // Methode zum Verarbeiten von POST-Methoden-Anfragen
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Servlet Filter Mapping in Web.xml

Filter definieren und dann auf eine URL oder Servlet mappen, was im Wesentlichen dem Definieren eines Servlets und dem Mappen auf ein URL-Muster entspricht. In der Deployment-Description-Datei web.xml unterhalb der filter-Tags den folgenden Eintrag zu erstellen:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app>  
<filter>
  <filter-name>LogFilter</filter-name>
  <filter-class>com.w3codebox.test.LogFilter</filter-class>
  <init-param>
    <param-name>Site</param-name>
    <param-value>Grund教程网</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>LogFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>  
  <!-- Klassenname -->  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- im Paket -->  
  <servlet-class>com.w3codebox.test.DisplayHeader</servlet-class>  
</servlet>  
<servlet-mapping>  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- besuchte Website -->  
  <url-pattern>/TomcatTest/DisplayHeader</url-pattern>  
</servlet-mapping>  
</web-app>

Dieser Filter ist für alle Servlets geeignet, da wir im Konfigurationsdatei angegeben haben /* . Wenn Sie nur auf wenigen Servlets einen Filter anwenden möchten, können Sie einen bestimmten Servlet-Pfad angeben.

Versuchen Sie, jeden Servlet auf die gängigste Weise aufzurufen, und Sie werden die Protokolle sehen, die im Web-Server generiert werden. Sie können auch Log4Der Recorder wird verwendet, um die obigen Protokolle in eine separate Datei zu protokollieren.

Jetzt besuchen wir diese Beispiel-Adresse http://localhost:8080/TomcatTest/DisplayHeader, und überprüfen Sie dann die Ausgabe auf der Konsole, wie folgt:

Verwendung mehrerer Filter

Ein Web-Anwendung kann mehrere verschiedene Filter für spezifische Zwecke definieren. Angenommen, Sie definieren zwei Filter AuthenFilter und LogFilter。Sie müssen einen anderen Mapping wie unten beschrieben erstellen, der Rest der Verarbeitung ist ähnlich wie oben erwähnt:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>com.w3codebox.test.LogFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Parameter</param-value>
   </init-param>
</filter>
<filter>
   <filter-name>AuthenFilter</filter-name>
   <filter-class>com.w3codebox.test.AuthenFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Parameter</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>

Anwendungsorten der Filter

filter in web.xml-Die Reihenfolge des mapping-Elements bestimmt die Reihenfolge, in der der Web-Container die Filter auf Servlets anwendet. Um die Reihenfolge der Filter umzukehren, müssen Sie einfach die Reihenfolge der filter im web.xml-Datei umkehren-mapping-Element ausreichend.

Zum Beispiel wird im obigen Beispiel zunächst LogFilter angewendet und dann AuthenFilter, aber im folgenden Beispiel wird diese Reihenfolge umgekehrt:

<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>

web.xml-Konfigurationsbeschreibung der verschiedenen Knoten

  • <filter>Ein Filter zu spezifizieren.

    • <filter-name>Wird verwendet, um einem Filter einen Namen zu zuweisen, der Inhalt dieses Elements darf nicht leer sein.

    • <filter-class>Element wird verwendet, um den vollständigen限定类名 des Filters zu spezifizieren.

    • <init-param>Element wird verwendet, um Initialisierungsparameter für den Filter zu spezifizieren, seine Unterlemente <param-name>Den Namen des Parameters zu spezifizieren, <param-value>Der Wert des Parameters zu spezifizieren.

    • In einem Filter kann das Interface-Objekt FilterConfig verwendet werden, um Initialisierungsparameter abzurufen.

  • <filter-mapping>Element wird verwendet, um die Ressourcen zu setzen, die ein Filter abfangen muss. Eine von einem Filter abgefangene Ressource kann auf zwei Arten angegeben werden: Servlet-Name und der Anfragemuster der Ressourcen-Adresse

    • <filter-name>Der Name des Elements, um den Filter-Registernamen zu setzen. Dieser Wert muss der Name eines Filters sein, der im <filter>-Element deklariert wurde.

    • <url-pattern> setzt den Pfad der Anfragen, die der Filter abfangen soll (URL-Stil des mit dem Filter verbundenen URL)

  • <servlet-name> bestimmt den Namen des Servlets, das vom Filter abgefangen wird.

  • <dispatcher> bestimmt die Art und Weise, wie der Servlet-Container die von dem Filter abgefangenen Ressourcen aufruft, und kann REQUEST, INCLUDE, FORWARD oder ERROR sein, Standard ist REQUEST. Benutzer können mehrere <dispatcher>-Subelemente einrichten, um verschiedene Arten der Filter-Resourceaufrufe zu speichern.

  • Werte und Bedeutung der <dispatcher>-Subelemente

    • REQUEST:Wenn der Benutzer direkt auf die Seite zugreift, ruft der Webcontainer den Filter auf. Wenn die Zielressource über die Methoden include() oder forward() von RequestDispatcher erreicht wird, wird der Filter nicht aufgerufen.

    • INCLUDE:Wenn die Zielressource über die Methode include() von RequestDispatcher erreicht wird, wird dieser Filter aufgerufen. Außerhalb dieser Bedingungen wird der Filter nicht aufgerufen.

    • FORWARD:Wenn die Zielressource über die Methode forward() von RequestDispatcher erreicht wird, wird dieser Filter aufgerufen. Außerhalb dieser Bedingungen wird der Filter nicht aufgerufen.

    • ERROR:Wenn die Zielressource über ein deklaratives Fehlerbehandlungssystem aufgerufen wird, wird dieser Filter aufgerufen. Außerhalb dieser Bedingungen wird der Filter nicht aufgerufen.