Servlet Filter schreiben
Servlet-Filter können Anfragen und Antworten dynamisch abfangen, um die in der Anfrage oder Antwort enthaltenen Informationen umzuwandeln oder zu verwenden.
Ein oder mehrere Servlet-Filter können an ein Servlet oder eine Gruppe von Servlets angehängt werden. Servlet-Filter können auch an JavaServer Pages (JSP)-Dateien und HTML-Seiten angehängt werden. Alle angehängten Servlet-Filter werden aufgerufen, bevor das Servlet ausgeführt wird.
Ein Servlet-Filter ist eine Java-Klasse, die in der Servlet-Programmierung verwendet werden kann und die folgenden Zwecke erfüllen kann:
- Abfangen von Client-Anfragen, bevor sie auf Backend-Ressourcen zugreifen.
- Verarbeiten von Server-Antworten, bevor sie an den Client zurückgesendet werden.
Verschiedene Arten von Filtern, die von der Spezifikation vorgeschlagen werden:
- Authentifizierungsfilter.
- Filter zur Datenkomprimierung.
- Verschlüsselungsfilter.
- Filter, die Ereignisse für den Ressourcenzugriff auslösen.
- Bildkonvertierungsfilter.
- Protokollierungs- und Auditfilter.
- MIME-TYPE-Kettenfilter.
- Tokenisierungsfilter.
- XSL/T-Filter, die XML-Inhalte transformieren.
Filter werden mit XML-Tags im Web-Deployment-Deskriptor (web.xml) deklariert und dann im Deployment-Deskriptor Ihrer Anwendung Servlet-Namen oder URL-Mustern zugeordnet.
Wenn der Web-Container die Webanwendung startet, erstellt er eine Instanz für jeden Filter, den Sie im Deployment-Deskriptor deklariert haben.
Die Ausführungsreihenfolge der Filter entspricht der Konfigurationsreihenfolge in der web.xml-Konfigurationsdatei; im Allgemeinen werden Filter vor allen Servlets konfiguriert.
Servlet-Filter-Methoden
Ein Filter ist eine Java-Klasse, die die Schnittstelle javax.servlet.Filter implementiert. Die Schnittstelle javax.servlet.Filter definiert drei Methoden:
| Nein. | Methode & Beschreibung |
|---|---|
| 1 | public void doFilter (ServletRequest, ServletResponse, FilterChain) Diese Methode führt die eigentliche Filteroperation aus. Wenn die Client-Anfragemethode mit der für den Filter festgelegten URL übereinstimmt, ruft der Servlet-Container zuerst die doFilter-Methode des Filters auf. FilterChain ermöglicht dem Benutzer den Zugriff auf nachfolgende Filter. |
| 2 | public void init(FilterConfig filterConfig) Wenn die Webanwendung startet, erstellt der Webserver eine Instanz des Filters und ruft deren init-Methode auf, liest die web.xml-Konfiguration und schließt die Objektinitialisierung ab, um sich so auf das Abfangen nachfolgender Benutzeranfragen vorzubereiten (das Filterobjekt wird nur einmal erstellt, und die init-Methode wird ebenfalls nur einmal ausgeführt). Über den Parameter der init-Methode können Entwickler das FilterConfig-Objekt abrufen, das die aktuelle Filterkonfigurationsinformation darstellt. |
| 3 | public void destroy() Der Servlet-Container ruft diese Methode auf, bevor er die Filterinstanz zerstört, und gibt in dieser Methode die vom Servlet-Filter belegten Ressourcen frei. |
Verwenden von FilterConfig
Die init-Methode von Filter stellt ein FilterConfig-Objekt bereit.
Beispielsweise wird die Datei web.xml wie folgt konfiguriert:
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.example.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>Example</param-value>
</init-param>
</filter>
Verwenden Sie das FilterConfig-Objekt in der init-Methode, um Parameter abzurufen:
public void init(FilterConfig config) throws ServletException {
// 获取初始化参数
String site = config.getInitParameter("Site");
// 输出初始化参数
System.out.println("网站名称: " + site);
}
Servlet-Filter-Beispiel
Das Folgende ist ein Servlet-Filter-Beispiel, das den Namen und die Adresse der Website ausgibt. Dieses Beispiel vermittelt Ihnen ein grundlegendes Verständnis von Servlet-Filtern. Sie können dieselben Konzepte verwenden, um komplexere Filteranwendungen zu schreiben:
package com.example.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://www.example.com");
// 把请求传回过滤链
chain.doFilter(request,response);
}
public void destroy( ){
/* 在 Filter 实例被 Web 容器从服务移除之前调用 */
}
}
Hier verwenden wir die zuvor erwähnte DisplayHeader.java als Beispiel:
//导入必需的 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 请求实例 - Example实例";
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 名称</th><th>Header 值</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>");
}
// 处理 POST 方法请求的方法
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Servlet-Filter-Zuordnung in Web.xml
Das Definieren eines Filters und dessen anschließende Zuordnung zu einer URL oder einem Servlet ist ungefähr dasselbe wie das Definieren eines Servlets und dessen anschließende Zuordnung zu einem URL-Muster. In der Deployment-Descriptor-Dateiweb.xmlerstelle den folgenden Eintrag für das Filter-Tag:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.example.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>Example</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<!-- 类名 -->
<servlet-name>DisplayHeader</servlet-name>
<!-- 所在的包 -->
<servlet-class>com.example.test.DisplayHeader</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayHeader</servlet-name>
<!-- 访问的网址 -->
<url-pattern>/TomcatTest/DisplayHeader</url-pattern>
</servlet-mapping>
</web-app>
Der obige Filter gilt für alle Servlets, da wir in der Konfiguration festgelegt haben/*. Wenn Sie den Filter nur auf einige Servlets anwenden möchten, können Sie einen bestimmten Servlet-Pfad angeben.
Versuchen Sie nun, ein beliebiges Servlet auf die übliche Weise aufzurufen, und Sie werden die im Webserver generierten Protokolle sehen. Sie können auch einen Log4J-Logger verwenden, um die obigen Protokolle in einer separaten Datei aufzuzeichnen.
Als Nächstes besuchen wir diese Beispieladressehttp://localhost:8080/TomcatTest/DisplayHeaderund sehen uns dann die Ausgabe in der Konsole an, wie unten gezeigt:

Mehrere Filter verwenden
Webanwendungen können mehrere verschiedene Filter für bestimmte Zwecke definieren. Angenommen, Sie definieren zwei FilterAuthenFilterundLogFilter. Sie müssen ein anderes Mapping erstellen, wie unten beschrieben; der restliche Verarbeitungsablauf ist ungefähr derselbe wie oben erläutert:
<filter> <filter-name>LogFilter</filter-name> <filter-class>com.example.test.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>com.example.test.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>
Reihenfolge der Filteranwendung
Die Reihenfolge der filter-mapping-Elemente in web.xml bestimmt die Reihenfolge, in der der Web-Container Filter auf Servlets anwendet. Um die Reihenfolge der Filter umzukehren, müssen Sie nur die filter-mapping-Elemente in der web.xml-Datei umkehren.
Zum Beispiel wendet das obige Beispiel zuerst LogFilter und dann AuthenFilter an, aber das folgende Beispiel kehrt diese Reihenfolge um:
<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>
Erläuterung der einzelnen Knoten in der web.xml-Konfiguration
<filter>Gibt einen Filter an.<filter-name>Dient zum Angeben eines Namens für den Filter; der Inhalt dieses Elements darf nicht leer sein.<filter-class>Dieses Element wird verwendet, um den vollqualifizierten Klassennamen des Filters anzugeben.<init-param>Dieses Element wird verwendet, um Initialisierungsparameter für den Filter anzugeben. Seine untergeordneten Elemente<param-name>geben den Parameternamen an,<param-value>und geben den Parameterwert an.- Im Filter können Sie
FilterConfigdas FilterConfig-Schnittstellenobjekt, um auf die Initialisierungsparameter zuzugreifen.
<filter-mapping>Dieses Element wird verwendet, um die Ressourcen festzulegen, für deren Abfangen ein Filter verantwortlich ist. Die von einem Filter abgefangenen Ressourcen können auf zwei Arten angegeben werden: Servlet-Name und Anfragepfad für den Ressourcenzugriff.<filter-name>Das untergeordnete Element wird verwendet, um den Registrierungsnamen des Filters festzulegen. Dieser Wert muss der Name eines Filters sein, der deklariert ist in<filter>dem <filter>-Element.<url-pattern>Legt den vom Filter abgefangenen Anfragepfad fest (das dem Filter zugeordnete URL-Muster).
<servlet-name>Gibt den Namen des vom Filter abgefangenen Servlets an.<dispatcher>Legt fest, auf welche Weise die vom Filter abgefangene Ressource vom Servlet-Container aufgerufen wird; sie kann seinREQUEST,INCLUDE,FORWARDundERROReine von, der Standard istREQUEST. Benutzer können mehrere<dispatcher>untergeordnete Elemente, um anzugeben, dass der Filter mehrere Aufrufmethoden der Ressource abfängt.<dispatcher>Die Werte, auf die das untergeordnete Element gesetzt werden kann, und ihre BedeutungenREQUEST: Wenn der Benutzer direkt auf die Seite zugreift, ruft der Web-Container den Filter auf. Wenn auf die Zielressource über die Methoden include() oder forward() von RequestDispatcher zugegriffen wird, wird der Filter nicht aufgerufen.INCLUDE: Wenn auf die Zielressource über die Methode include() von RequestDispatcher zugegriffen wird, wird der Filter aufgerufen. Andernfalls wird der Filter nicht aufgerufen.FORWARD: Wenn auf die Zielressource über die Methode forward() von RequestDispatcher zugegriffen wird, wird der Filter aufgerufen. Andernfalls wird der Filter nicht aufgerufen.ERROR: Wenn die Zielressource über den deklarativen Ausnahmebehandlungsmechanismus aufgerufen wird, wird der Filter aufgerufen. Andernfalls wird der Filter nicht aufgerufen.