Inleiding tot filters
Maar dat is niet alles. Je denkt echt niet dat servlets zo eenvoudig zijn, of wel?
Naast de servlets die we al hebben geanalyseerd, zijn er ook zogenaamde “utility servlets” - filters . Ze lijken erg op servlets, maar hun belangrijkste taak is om servlets te helpen bij het verwerken van aanvragen.
Een filter is als een secretaresse en een servlet is als een regisseur. Voordat het document het bureau van de directeur bereikt, gaat het door de handen van de secretaris. En na ondertekening door de directeur gaat het weer naar de secretaris, bijvoorbeeld al als uitgaande correspondentie.
Zo'n secretaresse kan een deel van de verzoeken aan de directeur afwijzen (bijvoorbeeld spam). Of geef standaardantwoorden op hem bekende vragen (“de directeur is niet aanwezig”). Enzovoort. Bovendien kunnen er meerdere van dergelijke secretaresses zijn: de een filtert spam voor alle directeuren tegelijk, de ander kan verzoeken tussen verschillende directeuren doorsturen, en dergelijke.
Filters werken op dezelfde manier.
Klassen Filter, FilterChain, FilterConfig
Filters lijken erg op servlets, maar met een paar kleine verschillen. Om uw eigen filter te schrijven, moet u overerven van het javax.servlet.Filter
.
Het filter heeft ook methoden init()
en destroy()
. In plaats van een methode service()
heeft een filter een doFilter()
. En heeft zelfs zijn eigen klasse FilterConfig. Het filter wordt ook toegevoegd aan de servlet in het web.xml-bestand of via de @WebFilter-annotatie.
Lijst met methoden:
methoden | Beschrijving | |
---|---|---|
1 | init(FilterConfig config) |
filterinitialisatie |
2 | destroy() |
filter lossen |
3 | doFilter(ServletRequest , ServletResponse, FilterChain) |
verzoekverwerking (filteren) |
Wat is het verschil tussen een servlet en een filter?
Er kunnen verschillende filters zijn en deze verwerken het verzoek (en antwoord) achtereenvolgens. Ze zijn gecombineerd tot een zogenaamde ketting - en er is zelfs een speciale klasse voor FilterChain
.
Nadat je het verzoek in de methode hebt verwerkt, moet je de methode van het volgende filter in de keten doFilter()
aanroepen . doFilter()
Voorbeeld:
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() {
}
}
Eigenlijk kun je de antwoordtekst niet zo toevoegen . Formeel zijn filters en servlets onafhankelijk van elkaar en kunnen onafhankelijk van elkaar worden gewijzigd. Ze kunnen op verschillende tijdstippen door verschillende ontwikkelaars worden geschreven. De filterfunctie is slechts een servicefunctie, bijvoorbeeld:
- Loggen van alle inkomende verzoeken (en reacties)
- Data compressie
- Versleuteling (en ontsleuteling) van gegevens
- Vraag gegevensvalidatie aan
- Voeg gewenste kopteksten toe of verwijder ze
- Verzoeken omleiden
- Toegangscontrole (controleren of de gebruiker is ingelogd)
RequestDispatcher-klasse
doFilter()
Soms kan het nodig zijn om een andere servlet aan te roepen terwijl er binnen een methode een filter draait . Hiervoor heeft de container een speciaal object RequestDispatcher
.
Je kunt het op twee manieren krijgen:
- Bij het voorwerp
HttpServletRequest
- Bij het voorwerp
ServletContext
Dit object kan worden gebruikt om een bestaand verzoek om te leiden naar een andere servlet . Zo bleek de gebruiker niet geautoriseerd te zijn en willen we hem een pagina met autorisatie laten zien. Welnu, of er was een fout op de server en we willen een foutpagina aan de gebruiker tonen :)
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);
}
}
U kunt ook bellen RequestDispatcher
vanuit een 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() {
}
}
Houd er rekening mee dat het verzoek in de methode wordt afgehandeld en dat u na gebruik forward()
niet hoeft te bellen .doFilter()
RequestDispatcher
Vergelijking van omleiding en doorsturen
En nog een belangrijk punt. Als u de gebruiker wilt omleiden naar een andere URI in uw servlet, dan kunt u dit op twee manieren doen:
redirect
forward
We hebben ze al geanalyseerd, maar voor het gemak zeg ik het nog een keer.
Wanneer u via een oproep omleidtresponse.sendRedirect("link")
, stuurt de server een antwoord terug naar de browser (client) 302
en de link die u hebt opgegeven. En de browser downloadt, na analyse van de reactie van de server, de link die u hebt gepasseerd. Dat wil zeggen, de link in de browser verandert in een nieuwe.
Als u doorstuurt via een call requestDispatcher.forward()
, wordt er een nieuw verzoek gedaan in de container en stuurt uw servlet zijn antwoord naar de browser (client) als antwoord van uw servlet. In dit geval ontvangt de browser een reactie van de nieuwe servlet, maar verandert de link in de browser niet.
GO TO FULL VERSION