Bevezetés a szűrőkbe
De ez még nem minden. Tényleg nem gondolja, hogy a servletek ilyen egyszerűek, igaz?
Az általunk már elemzett szervletek mellett léteznek úgynevezett „segédkiszolgálók” - szűrők is . Nagyon hasonlítanak a servletekhez, de fő feladatuk az, hogy segítsenek a szervleteknek feldolgozni a kéréseket.
A szűrő olyan, mint egy titkár, a szervlet pedig olyan, mint egy igazgató. Mielőtt a dokumentum az igazgatói asztalhoz kerül, átmegy a titkár kezén. És miután az igazgató aláírta, ismét a titkárhoz kerül, már például kimenő levelezésként.
Egy ilyen titkár elutasíthatja az igazgatóhoz intézett kérések egy részét (például spam). Vagy adjon standard válaszokat az általa ismert kérdésekre ("a rendező nincs a helyén"). Stb. Sőt, több ilyen titkár is lehet: az egyik egyszerre tudja szűrni a spameket az összes igazgató számára, a másik át tudja küldeni a kéréseket a különböző igazgatók között, és hasonlók.
A szűrők ugyanúgy működnek.
Osztályok Filter, FilterChain, FilterConfig
A szűrők nagyon hasonlítanak a szervletekhez, de van néhány apró eltérés. Saját szűrő írásához örökölnie kell a javax.servlet.Filter
.
A szűrőnek vannak metódusai init()
és destroy()
. Metódus helyett service()
egy szűrőnek van egy doFilter()
. És még saját FilterConfig osztálya is van. A szűrő a web.xml fájlban vagy a @WebFilter megjegyzésen keresztül is hozzáadódik a szervlethez.
A módszerek listája:
Mód | Leírás | |
---|---|---|
1 | init(FilterConfig config) |
szűrő inicializálása |
2 | destroy() |
szűrő kirakodás |
3 | doFilter(ServletRequest , ServletResponse, FilterChain) |
kérés feldolgozása (szűrés) |
Mi a különbség a servlet és a szűrő között?
Több szűrő is lehet, amelyek egymás után dolgozzák fel a kérést (és a választ). Egy úgynevezett láncba egyesítik őket - és még külön osztály is van számukra FilterChain
.
A metódusban a kérés feldolgozása után doFilter()
meg kell hívnia doFilter()
a lánc következő szűrőjének metódusát. Példa:
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() {
}
}
Valójában nem adhatja hozzá így a válasz törzsét . Formálisan a szűrők és a szervletek függetlenek egymástól, és egymástól függetlenül változtathatók. Különböző fejlesztők különböző időpontokban írhatják őket. A szűrő funkció csak egy szervizfunkció, például:
- Minden bejövő kérés (és válasz) naplózása
- Adattömörítés
- Az adatok titkosítása (és visszafejtése).
- Adatérvényesítés kérése
- A kívánt fejlécek hozzáadása/eltávolítása
- Átirányítási kérelmek
- Hozzáférés-vezérlés (ellenőrzi, hogy a felhasználó be van-e jelentkezve)
RequestDiszpécser osztály
doFilter()
Néha szükség lehet egy másik szervlet meghívására, miközben egy metóduson belül egy szűrő fut . Ehhez a tárolónak van egy speciális objektuma RequestDispatcher
.
Kétféleképpen szerezheti be:
- Az objektumnál
HttpServletRequest
- Az objektumnál
ServletContext
Ez az objektum használható egy meglévő kérés másik szervletre való átirányítására . Például kiderült, hogy a felhasználó nem jogosult, és szeretnénk neki egy oldalt megjeleníteni jogosultsággal. Nos, vagy hiba történt a szerveren és egy hibaoldalt szeretnénk megjeleníteni a felhasználónak :)
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);
}
}
RequestDispatcher
Szűrőből is hívhat .
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() {
}
}
Vegye figyelembe, hogy a kérést a metódus kezeli , és használat után forward()
nincs szükség hívásra .doFilter()
RequestDispatcher
Az átirányítás és a továbbítás összehasonlítása
És még egy fontos szempont. Ha a felhasználót egy másik URI-re szeretné átirányítani a szervletben, akkor ezt kétféleképpen teheti meg:
redirect
forward
Már elemeztük őket, de a kényelem kedvéért még egyszer elmondom.
Ha híváson keresztül irányít átresponse.sendRedirect("link")
, a szerver visszaküldi a böngészőnek (kliensnek) a választ 302
és az Ön által megadott hivatkozást. A böngésző pedig a szerver válaszának elemzése után letölti az átadott linket. Vagyis a böngészőben lévő hivatkozás egy újra változik.
Ha híváson keresztül továbbítrequestDispatcher.forward()
, akkor egy új kérés érkezik a tárolón belül, és a servlet a servlet válaszaként elküldi a választ a böngészőnek (kliensnek). Ebben az esetben a böngésző választ kap az új szervlettől, de a böngészőben lévő hivatkozás nem változik.
GO TO FULL VERSION