Panimula sa mga filter

Ngunit hindi lang iyon. Sa palagay mo ay hindi ganoon kasimple ang mga servlet, di ba?

Bilang karagdagan sa mga servlet na nasuri na namin, mayroon ding mga tinatawag na "utility servlets" - mga filter . Ang mga ito ay halos kapareho sa mga servlet, ngunit ang kanilang pangunahing trabaho ay upang matulungan ang mga servlet na magproseso ng mga kahilingan.

Ang filter ay parang sekretarya, at ang servlet ay parang direktor. Bago makarating ang dokumento sa mesa ng direktor, dadaan ito sa mga kamay ng kalihim. At pagkatapos na pirmahan ito ng direktor, muli itong mapupunta sa sekretarya, na bilang mga palabas na sulat, halimbawa.

Maaaring tanggihan ng naturang sekretarya ang ilan sa mga kahilingan sa direktor (halimbawa, spam). O magbigay ng karaniwang mga sagot sa mga tanong na alam niya (“wala ang direktor sa lugar”). At iba pa. Higit pa rito, maaaring mayroong ilang mga naturang sekretarya: ang isa ay maaaring mag-filter ng spam para sa lahat ng mga direktor nang sabay-sabay, ang isa ay maaaring maglipat ng mga kahilingan sa pagitan ng iba't ibang mga direktor, at mga katulad nito.

Gumagana ang mga filter sa parehong paraan.

mga utility servlet”

Filter ng Mga Klase, FilterChain, FilterConfig

Ang mga filter ay halos kapareho sa mga servlet, ngunit may ilang maliliit na pagkakaiba. Upang magsulat ng sarili mong filter, kailangan mong magmana mula sa javax.servlet.Filter.

Ang filter ay mayroon ding mga pamamaraan init()at destroy(). Sa halip na isang paraan, service()ang isang filter ay may doFilter(). At kahit na may sarili nitong klase FilterConfig. Idinaragdag din ang filter sa servlet sa web.xml file o sa pamamagitan ng @WebFilter annotation.

Listahan ng mga pamamaraan:

Paraan Paglalarawan
1 init(FilterConfig config) pagsisimula ng filter
2 destroy() pag-alis ng filter
3 doFilter(ServletRequest , ServletResponse, FilterChain) paghiling ng pagproseso (pag-filter)

Ano ang pagkakaiba sa pagitan ng isang servlet at isang filter?

Maaaring may ilang mga filter, at sunud-sunod nilang pinoproseso ang kahilingan (at tugon). Ang mga ito ay pinagsama sa isang tinatawag na chain - at mayroong isang espesyal na klase para sa kanila FilterChain.

Pagkatapos iproseso ang kahilingan sa pamamaraan, doFilter()kailangan mong tawagan ang paraan doFilter()ng susunod na filter sa chain. Halimbawa:

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() {
  }
}

Sa totoo lang, hindi mo maaaring idagdag ang katawan ng tugon na ganoon . Sa pormal, ang mga filter at servlet ay independiyente sa isa't isa at maaaring mabago nang nakapag-iisa. Maaari silang isulat ng iba't ibang mga developer sa iba't ibang panahon. Ang function ng filter ay isang function ng serbisyo lamang, halimbawa:

  • Pag-log sa lahat ng mga papasok na kahilingan (at mga tugon)
  • Pag-compress ng data
  • Pag-encrypt (at pag-decryption) ng data
  • Humiling ng Pagpapatunay ng Data
  • Magdagdag/mag-alis ng mga gustong header
  • Mga kahilingan sa pag-redirect
  • Access control (pagsusuri kung naka-log in ang user)

RequestDispatcher klase

doFilter() Minsan maaaring kailanganin na tumawag ng isa pang servlet habang tumatakbo ang isang filter sa loob ng isang pamamaraan . Upang gawin ito, ang lalagyan ay may isang espesyal na bagay RequestDispatcher.

Makukuha mo ito sa dalawang paraan:

  • Sa bagayHttpServletRequest
  • Sa bagayServletContext

Ang bagay na ito ay maaaring gamitin upang i-redirect ang isang umiiral na kahilingan sa isa pang servlet . Halimbawa, lumabas na hindi awtorisado ang user at gusto naming ipakita sa kanya ang isang page na may pahintulot. Well, o nagkaroon ng error sa server at gusto naming magpakita ng error page sa user :)

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);
    }
}

Maaari ka ring tumawag RequestDispatchermula sa isang 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() {
  }
}

Tandaan na ang kahilingan ay hahawakan sa pamamaraan forward()at hindi na kailangang tumawag doFilter()pagkatapos gamitin RequestDispatcher.

Paghahambing ng pag-redirect at pasulong

At isa pang mahalagang punto. Kung gusto mong i-redirect ang user sa isa pang URI sa iyong servlet, magagawa mo ito sa dalawang paraan:

  • redirect
  • forward

Nasuri na namin ang mga ito, ngunit para sa kaginhawahan ay sasabihin ko itong muli.

Kapag nag-redirect ka sa pamamagitan ng isang tawag response.sendRedirect("link"), ipapadala ng server pabalik sa browser (client) ang isang tugon 302at ang link na iyong tinukoy. At ang browser, pagkatapos suriin ang tugon ng server, dina-download ang link na iyong ipinasa. Iyon ay, ang link sa browser ay nagbabago sa isang bago.

Kung magpapasa ka sa pamamagitan ng isang tawag requestDispatcher.forward(), pagkatapos ay isang bagong kahilingan ang gagawin sa loob ng lalagyan, at ipapadala ng iyong servlet ang tugon nito sa browser (kliyente) bilang tugon ng iyong servlet. Sa kasong ito, ang browser ay tumatanggap ng tugon mula sa bagong servlet, ngunit ang link sa browser ay hindi nagbabago.