Introduksjon til filtre

Men det er ikke alt. Du tror virkelig ikke servlets er så enkle, gjør du?

I tillegg til servletene som vi allerede har analysert, finnes det også såkalte «utility servlets» -filtre . De ligner veldig på servlets, men deres hovedoppgave er å hjelpe servlets med å behandle forespørsler.

Et filter er som en sekretær, og en servlet er som en regissør. Før dokumentet når direktørens skrivebord, vil det gå gjennom hendene på sekretæren. Og etter at direktøren har skrevet under, vil den igjen gå til sekretæren, allerede som utgående korrespondanse, for eksempel.

En slik sekretær kan avvise noen av forespørslene til direktøren (for eksempel spam). Eller gi standardsvar på spørsmål kjent for ham ("regissøren er ikke på plass"). Og så videre. Dessuten kan det være flere slike sekretærer: en kan filtrere spam for alle direktører samtidig, den andre kan overføre forespørsler mellom forskjellige direktører og lignende.

Filtre fungerer på samme måte.

verktøyservlets"

Klasser Filter, FilterChain, FilterConfig

Filtre ligner veldig på servlets, men med et par små forskjeller. For å skrive ditt eget filter, må du arve fra javax.servlet.Filter.

Filteret har også metoder init()og destroy(). I stedet for en metode service()har et filter en doFilter(). Og har til og med sin egen klasse FilterConfig. Filteret legges også til servleten i web.xml-filen eller via @WebFilter-kommentaren.

Liste over metoder:

Metoder Beskrivelse
1 init(FilterConfig config) filterinitialisering
2 destroy() filtertømming
3 doFilter(ServletRequest , ServletResponse, FilterChain) forespørselsbehandling (filtrering)

Hva er forskjellen mellom en servlet og et filter?

Det kan være flere filtre, og de behandler forespørselen (og svaret) sekvensielt. De er kombinert til en såkalt kjede - og det er til og med en spesialklasse for dem FilterChain.

Etter å ha behandlet forespørselen i metoden, doFilter()må du ringe metoden doFilter()til neste filter i kjeden. Eksempel:

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() {
  }
}

Du kan faktisk ikke legge til svarteksten slik . Formelt sett er filtre og servlets uavhengige av hverandre og kan endres uavhengig av hverandre. De kan skrives av forskjellige utviklere til forskjellige tider. Filterfunksjonen er bare en servicefunksjon, for eksempel:

  • Logger alle innkommende forespørsler (og svar)
  • Datakomprimering
  • Kryptering (og dekryptering) av data
  • Be om datavalidering
  • Legg til/fjern ønskede overskrifter
  • Viderekoblingsforespørsler
  • Tilgangskontroll (sjekker om brukeren er pålogget)

RequestDispatcher-klasse

doFilter() Noen ganger kan det være nødvendig å kalle en annen servlet mens et filter kjører i en metode . For å gjøre dette har beholderen et spesielt objekt RequestDispatcher.

Du kan få det på to måter:

  • Ved objektetHttpServletRequest
  • Ved objektetServletContext

Dette objektet kan brukes til å omdirigere en eksisterende forespørsel til en annen servlet . For eksempel viste det seg at brukeren ikke er autorisert og vi ønsker å vise ham en side med autorisasjon. Vel, eller det var en feil på serveren og vi ønsker å vise en feilside til brukeren :)

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);
    }
}

Du kan også ringe RequestDispatcherfra et filter.

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() {
  }
}

Merk at forespørselen vil bli behandlet i metoden forward()og det er ikke nødvendig å ringe doFilter()etter bruk RequestDispatcher.

Sammenligning av omdirigering og videresending

Og enda et viktig poeng. Hvis du vil omdirigere brukeren til en annen URI i servleten din, kan du gjøre dette på to måter:

  • redirect
  • forward

Vi har allerede analysert dem, men for enkelhets skyld vil jeg si det igjen.

Når du omdirigerer via et anrop response.sendRedirect("link"), sender serveren tilbake til nettleseren (klienten) et svar 302og lenken du spesifiserte. Og nettleseren, etter å ha analysert serversvaret, laster ned koblingen du sendte. Det vil si at lenken i nettleseren endres til en ny.

Hvis du viderekobler via et anrop requestDispatcher.forward(), blir det gjort en ny forespørsel inne i containeren, og servleten sender sitt svar til nettleseren (klienten) som servletens svar. I dette tilfellet mottar nettleseren et svar fra den nye servleten, men lenken i nettleseren endres ikke.