Introduktion till filter
Men det är inte allt. Du tycker verkligen inte att servlets är så enkelt, eller hur?
Utöver de servlets som vi redan har analyserat, finns det även så kallade "utility servlets" - filter . De är väldigt lika servlets, men deras huvudsakliga uppgift är att hjälpa servlets att behandla förfrågningar.
Ett filter är som en sekreterare och en servlet är som en regissör. Innan dokumentet når direktörens skrivbord kommer det att passera genom händerna på sekreteraren. Och efter att direktören skrivit under går den åter till sekreteraren, redan som utgående korrespondens till exempel.
En sådan sekreterare kan avslå vissa av förfrågningarna till direktören (till exempel spam). Eller ge standardsvar på frågor som han känner till ("direktören är inte på plats"). Och så vidare. Dessutom kan det finnas flera sådana sekreterare: en kan filtrera spam för alla direktörer samtidigt, den andra kan överföra förfrågningar mellan olika direktörer och liknande.
Filter fungerar på samma sätt.
![verktygsservlets”](https://cdn.codegym.cc/images/article/26d0e45b-ea47-4037-8b11-7dd08145ef61/512.jpeg)
Klasser Filter, FilterChain, FilterConfig
Filter är väldigt lika servlets, men med ett par små skillnader. För att skriva ditt eget filter måste du ärva från javax.servlet.Filter
.
Filtret har även metoder init()
och destroy()
. Istället för en metod service()
har ett filter en doFilter()
. Och har till och med sin egen klass FilterConfig. Filtret läggs också till i servleten i web.xml-filen eller via @WebFilter-kommentaren.
Lista över metoder:
Metoder | Beskrivning | |
---|---|---|
1 | init(FilterConfig config) |
filterinitiering |
2 | destroy() |
filteravlastning |
3 | doFilter(ServletRequest , ServletResponse, FilterChain) |
begäran bearbetning (filtrering) |
Vad är skillnaden mellan en servlet och ett filter?
Det kan finnas flera filter, och de behandlar begäran (och svaret) sekventiellt. De kombineras till en så kallad kedja - och det finns till och med en speciell klass för dem FilterChain
.
Efter att ha bearbetat begäran i metoden doFilter()
måste du anropa metoden doFilter()
för nästa filter i kedjan. Exempel:
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() {
}
}
Egentligen kan du inte lägga till svarstexten så . Formellt är filter och servlets oberoende av varandra och kan ändras oberoende av varandra. De kan skrivas av olika utvecklare vid olika tidpunkter. Filterfunktionen är bara en servicefunktion, till exempel:
- Loggar alla inkommande förfrågningar (och svar)
- Datakomprimering
- Kryptering (och dekryptering) av data
- Begär datavalidering
- Lägg till/ta bort önskade rubriker
- Omdirigeringsförfrågningar
- Åtkomstkontroll (kontrollerar om användaren är inloggad)
RequestDispatcher-klass
doFilter()
Ibland kan det vara nödvändigt att anropa en annan servlet medan ett filter körs inom en metod . För att göra detta har behållaren ett speciellt objekt RequestDispatcher
.
Du kan få det på två sätt:
- Vid objektet
HttpServletRequest
- Vid objektet
ServletContext
Detta objekt kan användas för att omdirigera en befintlig begäran till en annan servlet . Det visade sig till exempel att användaren inte är behörig och vi vill visa honom en sida med behörighet. Tja, eller så uppstod ett fel på servern och vi vill visa en felsida för användaren :)
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 också ringa RequestDispatcher
från ett 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() {
}
}
Observera att förfrågan kommer att hanteras i metoden forward()
och det finns ingen anledning att ringa doFilter()
efter användning RequestDispatcher
.
Jämförelse av omdirigering och vidarebefordran
Och ytterligare en viktig punkt. Om du vill omdirigera användaren till en annan URI i din servlet kan du göra detta på två sätt:
redirect
forward
Vi har redan analyserat dem, men för enkelhetens skull säger jag det igen.
När du omdirigerar via ett samtal response.sendRedirect("link")
skickar servern tillbaka till webbläsaren (klienten) ett svar 302
och länken du angett. Och webbläsaren, efter att ha analyserat serversvaret, laddar ner länken du skickade. Det vill säga länken i webbläsaren ändras till en ny.
Om du vidarekopplar via ett samtal requestDispatcher.forward()
görs en ny begäran inuti behållaren och din servlet skickar sitt svar till webbläsaren (klienten) som din servlets svar. I det här fallet får webbläsaren ett svar från den nya servleten, men länken i webbläsaren ändras inte.