Einführung in Filter

Aber das ist nicht alles. Sie glauben wirklich nicht, dass Servlets so einfach sind, oder?

Zusätzlich zu den Servlets, die wir bereits analysiert haben, gibt es auch sogenannte „Utility-Servlets“ – Filter . Sie sind Servlets sehr ähnlich, ihre Hauptaufgabe besteht jedoch darin, Servlets bei der Verarbeitung von Anfragen zu unterstützen.

Ein Filter ist wie ein Sekretär und ein Servlet ist wie ein Direktor. Bevor das Dokument den Schreibtisch des Direktors erreicht, gelangt es durch die Hände der Sekretärin. Und nachdem der Direktor es unterschrieben hat, geht es wieder an die Sekretärin, beispielsweise bereits als ausgehende Korrespondenz.

Eine solche Sekretärin kann einige Anfragen an den Direktor ablehnen (z. B. Spam). Oder geben Sie Standardantworten auf ihm bekannte Fragen („Der Regisseur ist nicht am richtigen Platz“). Usw. Darüber hinaus kann es mehrere solcher Sekretäre geben: Einer kann Spam für alle Direktoren gleichzeitig filtern, der andere kann Anfragen zwischen verschiedenen Direktoren weiterleiten und dergleichen.

Filter funktionieren auf die gleiche Weise.

Dienstprogramm-Servlets“

Klassen Filter, FilterChain, FilterConfig

Filter sind Servlets sehr ähnlich, weisen jedoch einige kleine Unterschiede auf. Um Ihren eigenen Filter zu schreiben, müssen Sie von erben javax.servlet.Filter.

Der Filter verfügt außerdem über Methoden init()und destroy(). Anstelle einer Methode service()verfügt ein Filter über eine doFilter(). Und hat sogar eine eigene Klasse FilterConfig. Der Filter wird dem Servlet auch in der Datei web.xml oder über die Annotation @WebFilter hinzugefügt.

Liste der Methoden:

Methoden Beschreibung
1 init(FilterConfig config) Filterinitialisierung
2 destroy() Entladen des Filters
3 doFilter(ServletRequest , ServletResponse, FilterChain) Anfragebearbeitung (Filterung)

Was ist der Unterschied zwischen einem Servlet und einem Filter?

Es können mehrere Filter vorhanden sein, die die Anfrage (und Antwort) nacheinander verarbeiten. Sie werden zu einer sogenannten Kette zusammengefasst – und für sie gibt es sogar eine eigene Klasse FilterChain.

Nachdem Sie die Anforderung in der Methode verarbeitet haben, müssen Sie die Methode des nächsten Filters in der Kette doFilter()aufrufen . doFilter()Beispiel:

public class MyFilter implements Filter {

  public void init(FilterConfig arg0) throws ServletException {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {

      PrintWriter out = resp.getWriter();
      out.print("Adding something before the body of the response");

      chain.doFilter(req, resp); // call the next filter in the chain

      out.print("Adding something after the body of the response");
    }

  public void destroy() {
  }
}

Eigentlich kann man den Antworttext nicht so hinzufügen . Formal sind Filter und Servlets unabhängig voneinander und können unabhängig voneinander geändert werden. Sie können von verschiedenen Entwicklern zu unterschiedlichen Zeiten geschrieben werden. Die Filterfunktion ist lediglich eine Servicefunktion, zum Beispiel:

  • Protokollierung aller eingehenden Anfragen (und Antworten)
  • Datenkompression
  • Verschlüsselung (und Entschlüsselung) von Daten
  • Fordern Sie eine Datenvalidierung an
  • Gewünschte Header hinzufügen/entfernen
  • Anfragen umleiten
  • Zugriffskontrolle (Prüfung, ob der Benutzer angemeldet ist)

RequestDispatcher-Klasse

doFilter() Manchmal kann es notwendig sein, ein anderes Servlet aufzurufen, während ein Filter innerhalb einer Methode ausgeführt wird . Zu diesem Zweck verfügt der Container über ein spezielles Objekt RequestDispatcher.

Sie können es auf zwei Arten erhalten:

  • Am ObjektHttpServletRequest
  • Am ObjektServletContext

Dieses Objekt kann verwendet werden, um eine bestehende Anfrage an ein anderes Servlet umzuleiten . Beispielsweise stellte sich heraus, dass der Benutzer nicht autorisiert ist und wir ihm eine Seite mit Autorisierung anzeigen möchten. Na ja, oder es ist ein Fehler auf dem Server aufgetreten und wir möchten dem Benutzer eine Fehlerseite anzeigen :)

public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws Exception {
           String path = "/error.html";
           ServletContext servletContext = this.getServletContext();
           RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
           requestDispatcher.forward(request, response);
    }
}

Sie können auch RequestDispatcherüber einen Filter aufrufen.

public class MyFilter implements Filter {

  public void init(FilterConfig arg0) throws ServletException {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {
           String path = "/error.html";
           ServletContext servletContext = req.getServletContext();
           RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
           requestDispatcher.forward(req, resp);
    }

  public void destroy() {
  }
}

Beachten Sie, dass die Anfrage in der Methode verarbeitet wird und nach der Verwendung forward()kein Aufruf erforderlich ist .doFilter()RequestDispatcher

Vergleich von Redirect und Forward

Und noch ein wichtiger Punkt. Wenn Sie den Benutzer zu einem anderen URI in Ihrem Servlet umleiten möchten, können Sie dies auf zwei Arten tun:

  • redirect
  • forward

Wir haben sie bereits analysiert, aber der Einfachheit halber werde ich es noch einmal sagen.

Wenn Sie über einen Anruf weiterleiten , sendet der Server eine Antwort und den von Ihnen angegebenen Link response.sendRedirect("link")an den Browser (Client) zurück . 302Und der Browser lädt nach der Analyse der Serverantwort den von Ihnen übergebenen Link herunter. Das heißt, der Link im Browser ändert sich zu einem neuen.

Wenn Sie über einen Aufruf weiterleitenrequestDispatcher.forward() , wird im Container eine neue Anfrage gestellt und Ihr Servlet sendet seine Antwort als Antwort Ihres Servlets an den Browser (Client). In diesem Fall erhält der Browser eine Antwort vom neuen Servlet, der Link im Browser ändert sich jedoch nicht.