Шинос шудан бо филтрҳо
Аммо ин ҳамааш нест. Росташро гӯям, ту намепиндорӣ, ки сервлетҳо ин қадар оддӣ сохта шудаанд?
Ғайр аз сервлетҳо, ки мо аллакай муҳокима кардем, боз ҳастанд онҳое, ки номашон “служебные сервлеты” — филтрҳо. Ҳамин гуна онҳо ба сервлетҳо монанданд, аммо вазифаи асосии онҳо ёрӣ додан ба сервлетҳо дар коркарди дархостҳо мебошад.
Филтр — мисли котиб аст, ва сервлет – директор. Пеш аз он ки ҳуҷҷат ба назди директор расад, он аз дасти котиб гузаронида мешавад. Ва баъди он ки директор онро имзо мекунад, он боз ба котиб мерасад, масалан, ҳамчун мукотибаи хориҷӣ.
Ҳамин гуна як котиб метавонад як қисм дархостҳоро ба директорро рад кунад (масалан, спам). Ё ҷавобҳои стандартӣ ба саволҳои маълумаш медиҳад (“директор дар ҷояш нест”). Ва ғайра. Баъзе имкониятҳои дигар вуҷуд доранд, ки якчанд котиб метавонад бошад: як ҷавобгӯ барои филтр кардани спам барои ҳамаи директорҳо, дигаре барои тақсим кардани дархостҳо миёни директорони гуногун ва ғайра.
Филтрҳо низ ҳамин гуна кор мекунанд:

Класҳои Filter, FilterChain, FilterConfig
Филтрҳо ба сервлетҳо хеле монанданд, аммо чанд фарқиятҳояшон ҳаст. Барои навиштани филтри худатон, бояд аз интерфейси javax.servlet.Filter
ворис шавед.
Дар филтр ҳамчунин методҳои init()
ва destroy()
ҳастанд. Ба ҷойи методи service()
дар филтр методи doFilter()
вуҷуд дорад. Ва ҳатто як класси махсуси худи FilterConfig дорад. Филтр инчунин дар файли web.xml ба сервлет дохил мешавад ё бо истифода аз аннотацияи @WebFilter.
Рӯйхати методҳо:
Методҳо | Тавсиф | |
---|---|---|
1 | init(FilterConfig config) |
инициативати филтр |
2 | destroy() |
фурӯши филтр |
3 | doFilter(ServletRequest , ServletResponse, FilterChain) |
коркард (филтр кардан) дархост |
Фарқи сервлет ва филтр дар чӣ аст?
Филтрҳо метавонанд чандтогӣ бошанд, ва онҳо дархост (ва ҷавоб) пай дар пай коркард мекунанд. Онҳо дар як занҷир муттаҳид шудаанд — ва барои онҳо ҳатто як класси махсуси FilterChain
вуҷуд дорад.
Пас аз коркарди дархост дар методи doFilter()
бояд методи doFilter()
-и филтри оянда дар занҷирро даъват кард. Намуна:
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("Дописываем что-то перед телом ответа");
chain.doFilter(req, resp); //ба филтри оянда дар занҷир даъват мекунем
out.print("Дописываем что-то после тела ответа");
}
public void destroy() {
}
}
Дар ҳақиқат, ҳамин гуна дар қисми ҷавоб илова кардан намемонад. Формално филтрҳо ва сервлетҳо аз якдигар мустақиланд ва метавонанд мустақилона тағйир дода шаванд. Онҳоро метавонистад дигар разработчикон дар замони дигар нависанд. Функсияи филтрҳо махсусан хизматрасонӣ аст, масалан:
- Логиронии ҳамаи дархостҳои воридшуда (ва ҷавобҳо)
- Фишурдани маълумот
- Шифргузорӣ (ва шифркушоии) маълумот
- Тасдиқи маълумоти дархост
- Илова/нест кардани сарлавҳаҳои зарурӣ
- Тақсим кардани дархостҳо
- Назорати дастрасӣ (санҷиши, баромадкорӣ)
Класси RequestDispatcher
Ҳангоми кор кардани филтр дар дохили методи doFilter()
зарурати даъват кардани дигар сервлет пайдошуда метавонад. Барои ин контейнер объекти махсуси RequestDispatcher
дорад.
Онро ду роҳ гирифтан мумкин аст:
- Бо объекти
HttpServletRequest
- Бо объекти
ServletContext
Ин объектро барои он истифода бурдан мумкин аст, ки дархостро ба дигар сервлет интиқол диҳад. Масалан, маълум шуд, ки истифодабаранда роҳ надорад ва мо мехоҳем, ки ба ӯ саҳифаи баромадкориро нишон диҳем. Ё хатогии сервер рух дод ва мо мехоҳем, ки ба истифодабаранда саҳифаи хатогиро нишон диҳем :)
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
аз филтр даъват кунӣ.
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() {
}
}
Таваҷҷӯҳ кун, ки дархост дар методи forward()
коркард мешавад, ва даъвати doFilter()
баъди истифодабарии RequestDispatcher
лозим нест.
Мукоиса кардани редирект ва форвард
Ва боз як нуқтаи муҳим. Агар дар сервлети худ ту хоҳӣ, ки истифодабарандаро ба URI-и дигар равона кунӣ, ин корро ду роҳи иҷро кардан мумкин аст:
redirect
forward
Мо онҳоро аллакай баррасӣ кардем, аммо барои осонӣ инро боз як бор мегӯям.
Вақте ту redirect мекунӣ тавассути даъвати response.sendRedirect("ссылка")
, сервер ба браузер (клиент) ҷавоби 302
ва пайванди нишон додашударо мефиристад. Ва браузер, пас аз таҳлили ҷавоби сервер, пайванди додаи ту гирифта мешавад. Яъне пайванди браузер ба нав табдил ёфта мешавад.
Агар ту forward мекунӣ тавассути даъвати requestDispatcher.forward()
, пас дархости нав дар дохили контейнер иҷро мешавад, ва ҷавобашро сервлети ту ба браузер (клиент) ҳамчун ҷавоби сервлети ту ирсол мекунад. Бо ин, браузер ҷавоби аз сервлети нав мегирад, аммо пайванди браузер тағир намеёбад.
GO TO FULL VERSION