Filtrlarga kirish
Lekin bu hammasi emas. Haqiqatan ham, servlеtlar shunchalik sodda deb o'ylaysanmi?
Biz ko'rib chiqqan servlеtlar bilan bir qatorda, yana "xizmat servlеtlari" deb ataladigan — filtrlar ham bor. Ular servlеtlarga juda o'xshash, lekin ularning asosiy vazifasi — so'rovlarni qayta ishlashda servlеtlarga yordam berish.
Filtr — bu sekretar, servlеt — direktor. Hujjat direktor stoliga tushmasdan oldin, sekretar qo'lidan o'tadi. Va direktor uni imzolaganidan so'ng, u yana sekretarga qaytadi, masalan, chiqish xati sifatida.
Bunday sekretar direktor tomonidan so‘rovlarning bir qismini (masalan, spam) rad etishi mumkin. Yoki unga yaxshi ma'lum bo'lgan savollarga standart javoblar berishi mumkin (“direktor joyida emas”). Va hokazo. Bundan tashqari, bunday sekretarlar bir nechta bo'lishi mumkin: biri barcha direktorlar uchun spamni filtrlashi mumkin, ikkinchisi turli direktorlar o'rtasida so'rovlarni oldirib turishi mumkin va hokazo.
Filtrlar ham xuddi shunday ishlaydi:
Filter, FilterChain, FilterConfig sinflari
Filtrlar servlеtlarga juda o'xshash, lekin bir necha kichik farqlar bilan. O'z filtringizni yozish uchun javax.servlet.Filter interfeysini meros olish kerak.
Filtrda init() va destroy() metodlar mavjud. service() metodi o'rniga, filtrda doFilter() metodi mavjud. Va hattoki, FilterConfig o'z sinfi ham mavjud. Filtr web.xml fayliga yoki @WebFilter annotatsiyasi yordamida servlеtga qo'shiladi.
Metodlar ro'yxati:
| Методы | Tavsif | |
|---|---|---|
| 1 | init(FilterConfig config) |
filtrni ishga tushirish |
| 2 | destroy() |
filtrni o'chirish |
| 3 | doFilter(ServletRequest , ServletResponse, FilterChain) |
so'rovni qayta ishlash (filtrlash) |
Servlеt va filtrning o'rtasidagi farq nimada?
Filtrlar bir nechta bo'lishi mumkin va ular so'rovni (va javobni) ketma-ket qayta ishlaydi. Ular zanjir deb ataladigan birlashtirilgan — va ular uchun maxsus FilterChain sinfi mavjud.
doFilter() metodida so'rovni qayta ishlagandan so'ng, zanjirdagi keyingi filterni doFilter() metodini chaqirish kerak. Misol:
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("Javob tanasidan oldin nimadir qo'shamiz");
chain.doFilter(req, resp); //zanjirdagi keyingi filterni chaqiramiz
out.print("Javob tanasidan keyin nimadir qo'shamiz");
}
public void destroy() {
}
}
Aslida javob tanasiga bunday qo'shish mumkin emas. Rasmiy ravishda filtrlar va servlеtlar bir-biridan mustaqil va mustaqil ravishda o'zgarishi mumkin. Ularni turli dasturchilar turli vaqtlarda yozishi mumkin. Filtrlarning vazifasi aynan xizmat ko'rsatish, masalan:
- Barcha kiruvchi so'rovlarni (va javoblarni) loglash
- Ma'lumotlarning siqilishi
- Ma'lumotlarning shifrlanishi (va shifrni yechish)
- So'rov ma'lumotlarini validatsiya qilish
- Kerakli sarlavhalarni qo'shish/olib tashlash
- So'rovlarni qayta yo'naltirish
- Kirish nazorati (foydalanuvchi kirganini tekshirish)
RequestDispatcher sinfi
Ba'zida doFilter() metodining ichida ishlayotgan filtr jarayonida boshqa servlеtni chaqirish zaruriyati tug'ilishi mumkin. Buning uchun konteynerda maxsus RequestDispatcher obyekti mavjud.
Uni ikki usulda olish mumkin:
HttpServletRequestobyekti orqaliServletContextobyekti orqali
Bu obyektni mavjud so‘rovni boshqa servlеtga yo‘naltirish uchun ishlatishingiz mumkin. Masalan, foydalanuvchi avtorizatsiyadan o‘tmaganini aniqladik va unga avtorizatsiya sahifasini ko‘rsatmoqchimiz. Yoki serverda xato yuz berdi va foydalanuvchiga xato sahifasini ko‘rsatmoqchimiz :)
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);
}
}
Filtrdan RequestDispatcherni chaqirishingiz ham mumkin.
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() {
}
}
Diqqat qilish kerakki, so'rov forward() metodida qayta ishlanadi, va RequestDispatcher dan foydalanishdan keyin doFilter()ni chaqirish shart emas.
Redirect va forwardni taqqoslash
Va yana bir muhim nuqta. Agar servletingizda foydalanuvchini boshqa URIda yo'naltirmoqchi bo'lsangiz, buni ikki usulda amalga oshirish mumkin:
redirectforward
Biz ularni allaqachon ko'rganmiz, lekin qulaylik uchun yana bir bor qayd etaman.
Sen redirectni response.sendRedirect("ссылка") chaqiruvi orqali bajarganingda, server brauzerga (klientga) 302 javobini va berilgan linkni yuboradi. Brauzer server javobini tahlil qilib, sen yuborgan linkni yuklab oladi. Ya'ni, brauzer linki yangi linkka o'zgaradi.
Agar sen forwardni requestDispatcher.forward() chaqiruvi orqali bajarganingda, yangi so'rov konteyner ichida bajariladi va servletingning javobi (klientga) brauzerga sening servleting javobi sifatida yuboriladi. Shu bilan brauzer yangi servleting javobini oladi, lekin brauzer linki o'zgarmaydi.
GO TO FULL VERSION