V predchádzajúcom článku o servletoch som na príkladoch ukázal jednoduchý spôsob zabezpečenia perzistencie servletu. V tomto článku znova využijem obľúbenú tému počítania prístupov. Tentoraz však na to, aby som predviedol prácu s cookies a prepisom URL. Tieto dve techniky sú určené okrem iného na uchovanie stavu medzi requestami (state tracking), pretože, ako dobre vieme, protokol HTTP je bezstavový.

Cookie servlet

Cookie je malé množstvo dát, ktoré si navzájom posiela server a browser. Server posiela dáta, ktoré v nezmenenej podobe bude potrebovať späť pri najbližšej „návšteve“ klienta. Toto je v jednoduchosti spôsob ako zabezpečiť uchovanie stavu medzi serverom a browserom.

Vytvorme si preto servlet a pomenujme ho CookieServlet. Tento servlet bude mať za úlohu vytvoriť a poslať cookie klientovi a následne poslané cookie získať a spracovať. Ak klient zavolá servlet po prvýkrát, servlet neobdrží potrebnú cookie, pretože ju klient zatiaľ nemá. Na túto skutočnosť treba pamätať pri návrhu kódu a v tom prípade je nutné vytvoriť novú inštanciu cookie a inicializovať premennú, predstavujúcu počet prístupov, na nulu. Ak servlet obdrží cookie nesúcu informáciu o počte prístupov, musí túto informáciu získať a nastaviť počet prístupov na správne číslo – skúste si príklad (zvýraznený kód CookieServlet.java).

package interval;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CookieServlet extends HttpServlet {
  protected void service(HttpServletRequest req,HttpServletResponse res)
      throws ServletException,IOException {
    int calledCount = 0;
    res.setContentType(„text/html;charset=windows-1250“);
    PrintWriter out = res.getWriter();
    out.println(„<HTML><TITLE>CookieServlet</TITLE><BODY>“);
    out.println(„<H2>Cookie Servlet:</H2><HR>“);
    if (getReqCookie(req,out,“calledCount“) == null) calledCount = 0;
    else calledCount = new Integer(getReqCookie(req,out,“calledCount“)).intValue();
    out.print(„Hodnota cookie <strong>calledCount</strong> „);
    out.print(„získaná z objektu request: „);
    if (calledCount == 0) out.println(“ NULL – cookie nenájdená<HR>“);
    else out.println(calledCount + „<HR>“);
    calledCount++;
    Cookie cookie = new Cookie(„calledCount“, new Integer(calledCount).toString());
    res.addCookie(cookie);
    out.println(„Hodnota cookie <strong>calledCount</strong> „);
    out.println(„odoslaná späť: “ + calledCount);
    out.println(„<HR></BODY><HTML>“);
    out.close();
  }
  private String getReqCookie(HttpServletRequest req,PrintWriter out,String name){
    Cookie[] cookies = req.getCookies();
    if (cookies != null && cookies.length > 0) {
      for(int i=0; i < cookies.length; i++) {
        if (cookies[i].getName().equals(name)) return (cookies[i].getValue());
      }
    }
  return null;
  }
}

Servlet prechádza cez obdržané pole objektov cookies a hľadá cookie s názvom calledCount. Ak ju nenájde, nastaví premennú calledCount na 0. Ak ju nájde, zistí jej hodnotu a priradí ju. Táto hodnota je následne inkrementovaná o jednotku, servlet vytvorí novú cookie s tým istým názvom a priradí jej novú hodnotu počítadla. Túto cookie potom odovzdá objektu response. Cookie je následne poslaná klientovi, ktorý ju uloží. Opakované volanie servletu spôsobí postupné zvyšovanie hodnoty počítadla.

Toto je jeden z možných spôsobov uchovania stavu medzi browserom a serverom. Má to však jeden háčik. A to, že väčšina browserov umožňuje užívateľovi vypnúť podporu používania (akceptovania) cookies. V tom prípade je možné použiť takzvaný URL rewriting (prepis URL).

URL rewriting servlet

Prepis URL je druhou možnosťou, použiteľnou pri požiadavke na uchovávanie stavu medzi jednotlivými requestami. Podstatou je, že parametre potrebné pre uchovávanie stavu „konverzácie“ sa pripájajú ako reťazce za URL. V našom príklade to bude jediný parameter, uchovávajúci počet prístupov, s názvom calledCount. Prepis URL sa často využíva pri sledovaní sedenia (session tracking) v prípade, ak klient neakceptuje cookies. Modifikujme predošlý príklad tak, aby sme použili rovnaký state tracking mechanizmus, ale s využitím prepisu URL. Aj tento príklad si môžete skúsiť on-line (zvýraznený kód URLWritingServlet.java).

package interval;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class URLWritingServlet extends HttpServlet {
  protected void service(HttpServletRequest req,HttpServletResponse res)
      throws ServletException,IOException {
    int calledCount = 0;
    res.setContentType(„text/html;charset=windows-1250“);
    PrintWriter out = res.getWriter();
    out.println(„<HTML><TITLE>URLWritingServlet</TITLE><BODY>“);
    out.println(„<H2>URL Rewriting Servlet:</H2><HR>“);
    calledCount = getReqURLInt(req,“calledCount“);
    out.println(„Hodnota URL parametra <strong>calledCount</strong> „);
    out.println(„získaná z objektu request: „);
    if (calledCount == 0) out.println(“ NULL – bez hodnoty<HR>“);
    else out.println(calledCount + „<HR>“);
    calledCount++;
    out.println(„Hodnota URL parametra <strong>calledCount</strong> „);
    out.println(„odoslaná späť: “ + calledCount);
    out.print(„<HR><P><A HREF=\“interval.URLWritingServlet“);
    out.print(„?calledCount=“ + calledCount + „\“>Click to reload servlet</A>“);
    out.println(„</BODY><HTML>“);
    out.close();
  }
  private int getReqURLInt(HttpServletRequest req,String name){
    int val = 0;
    if (req.getParameter(name)!= null) {
      val = new Integer(req.getParameter(name)).intValue();
    }
  return val;
  }
}

Ako som povedal, príklad funguje na rovnakom princípe ako predchádzajúci. Na rozdiel od neho však potrebný údaj (počet prístupov) prenášame prostredníctvom request parametra calledCount, ktorý najprv získame, vypíšeme a následne inkrementujeme o jednotku. Potom sa tento parameter pripojí k URL odkazujúcej na servlet.

Tento článok bol viac menej na odľahčenie. Obidva uvedené príklady sú veľmi jednoduché. V ďalšej časti sa pozrieme na prácu so sedeniami.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět