V predošlej časti sme prebrali teoretické aspekty práce s objektom HttpSession. Ukázali sme si ako session vytvoriť, naplniť atribútmi (objektmi), ako reagovať na vznik udalostí súvisiacich s objektom session a nakoniec ako session ukončiť. V dnešnej časti si vytvoríme a prejdeme praktický príklad využívajúci prácu s objektom session.

Ako v praxi funguje session tracking

Zopakujme si, že session tracking umožňuje servletu spojiť požiadavku s konkrétnym užívateľom (klientom). Umožňuje tak čiastočne vykompenzovať skutočnosť, že protokol HTTP je bezstavový. V praxi sa správa session zabezpečuje typicky dvoma spôsobmi:

1. Použitím cookies. Vieme, že cookie je malý textový súbor poslaný klientovi typicky na začiatku (pri vytvorení) session. V tomto prípade obsahuje reťazec predstavujúci session ID. Ak klient pokračuje v danej session, pošle toto cookie na server (servlet) aj s príslušnými požiadavkami. Použitie cookies je najbežnejší spôsob správy session. Servlet kontajner tento spôsob použije automaticky.

2. Spôsob nám už známy je URL rewriting. Spočíva okrem iného v tom, že všetky linky a presmerovania vytvorené servletom musia byť „zakódované“. Tým sa zabezpečí automatické pripojenie session ID ku každému odkazu. Toto riešenie je čiastočne nevýhodné, jednak pre tvorcov servletov ako aj pre samotných užívateľov, pretože session v tomto prípade nie je spravovaná prostredníctvom klasického URL. Druhá vec, ktorá mierne komplikuje problém, je to, že nie je možné použiť statické stránky. Všetky html stránky v danej session musia byť vytvorené dynamicky.

Z uvedeného vyplýva, že ak servlet vracia klientovi aj nejaké URL odkazy a aplikácia potrebuje využívať session tracking, musí programátor tieto odkazy spracovať metódou objektu response.encodeURL(„sendURL“). A to z toho dôvodu, že klient môže zakázať používanie cookies.

Popis príkladu

Vytvorme si teda nejaký kvázi reálny príklad, ktorý by aplikoval doteraz prebrané poznatky. Myslím, že celkom vhodná by bola problematika internetového nákupného košíka. Momentálne nie je dôležité, čo budeme predávať, aký široký bude sortiment a pod., ale to, ako vyriešime uchovanie obsahu nákupného košíka konkrétneho užívateľa a objednanie tovaru nachádzajúceho sa v košíku.

Majme úvodnú stránku (shop.jsp) s ponukou akciového tovaru. Na tejto stránke je možné do textfieldu zadať počet položiek konkrétneho výrobku, ktoré chceme vložiť do košíka. Samotné vloženie sa vykoná cez tlačítko „Vložiť tovar do košíka“. Týmto postupom si môžete viacnásobne doplniť tovar do košíka, pričom položky sa kumulujú. Ak ste skončili s výberom, tovar v košíku si objednáte tlačítkom „Objednať obsah košíka“. Dostanete prehľad objednaného tovaru s počtom kusov a košík bude vyprázdnený. Príklad je k dispozícii on-line.

shop.jsp

Takto vyzerá hlavná stránka nášho extrémne zjednodušeného akciového obchodu s elektronikou. Odporúčam vám otvoriť si zdrojový kód so zvýraznenou syntaxou. V hlavičke stránky shop.jsp je skriptovací blok, v ktorom ako prvé získam objekt aktuálnej session. Následne pod podmienkou, že ses.isNew() mi vráti true, naplním session atribútmi – položkami v ponuke s množstvom rovným 0. V bloku ešte nastavím časový interval expirácie session na 10 minút.

Nasleduje vytvorenie samotného formulára. Kód HTML vám vysvetlovať nebudem, určite je vám jasný. Dôležitejšie sú opäť niektoré časti Java kódu. V prvom rade si treba všimnúť, že relatívne URL, na ktoré odkazujem v atribúte action elementu form je vložené do metódy response.encodeURL(). Už som to spomínal vyššie. Ak klient zablokuje používanie cookies a programátor nepoužije túto metódu, servlet nemá šancu sledovať sedenie a pridávanie tovaru do košíka prakticky nebude fungovať. Naopak ak túto metódu použijete, k požadovanému URL bude automaticky pripojené session ID. Skúste si preto vypnúť vo vašom browseri cookies a sledujte, čo sa bude diať. Druhá vec, ktorú si treba všimnúť, je, akým spôsobom získam hodnoty jednotlivých atribútov z danej session, teda počty kusov jednotlivých tovarov v ponuke. Pri prvom načítaní sú rovné nule.

Na stránke shop.jsp posielam dáta z formulára na servlet s názvom shopservlet. V skutočnosti je jeho meno interval.ShoppingCartServlet. Aby bol požadovaný zdroj nájdený, musíme upraviť deskriptor webovej aplikácie nasledovne:

<servlet>
   <servlet-name>ShopCart</servlet-name>
   <servlet-class>interval.ShoppingCartServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>ShopCart</servlet-name>
   <url-pattern>/shopservlet</url-pattern>
</servlet-mapping>

Pozrime sa teda bližšie na samotný servlet pracujúci na pozadí nášho obchodu. Zvažoval som, či vložiť kód servletu do samotného článku, alebo do externej HTML stránky. Nakoniec som sa rozhodol pre druhú možnosť. Z jednoduchého dôvodu. A to, že kód je pomerne „široký“ a vtesnať ho do článku by bolo nemožné, bez krkolomného zalamovania riadkov. Okrem toho v externom súbore môžem zvýrazniť syntax kódu, aby bol lepšie čitateľný. Preto vám odporúčam otvoriť si teraz stránku s kódom servletu ShoopingCartServlet.

Najdôležitejšie na celom príklade je uvedomiť si, že session resp. objekt ktorý ju reprezentuje, je „globálny“. Inými slovami, keď na stránke shop.jsp niečo vložím do session, v servlete shopservlet, ktorý je súčasťou tej istej webovej aplikácie, môžem zo session vložené atribúty zase prečítať. Platí to aj opačne. A presne to využívam v príklade.

Pozrime sa, čo presne a ako servlet robí. Ako prvé nastavíme jazykové kódovanie v objekte request a požiadame o aktuálny objekt session. Potom si vyžiadame jednotlivé atribúty uložené v session. Keďže v session môžem mať uložené len objekty a ja potrebujem získať primitívny typ integer, musím vykonať prevod. To sa deje v nasledujúcom kroku. Teraz sa servlet rozdelí na dve časti na základe if {…} else {…}. Prvá časť sa vykoná vtedy, ak kliknete na tlačítko „Vložiť tovar do košíka“. Ak kliknete na druhé, vykoná sa časť else {…}. Takže ak sa rozhodnete vložiť tovar do košíka a vyplníte počet kusov, tieto hodnoty sú vyčítané z requestu a príslušné atribúty session sú o tieto hodnoty inkrementované. Následne ich opäť vložíme do session, resp. nahradíme tie pôvodné. Po vložení do session predáme riadenie znova stránke shop.jsp. Na podobné účely sa používa objekt javax.servlet.RequestDispatcher a jeho metóda forward().

V prípade, že sa rozhodnete objednať si obsah vášho košíka, v prvom rade treba zistiť, ktoré položky sú nenulové. Na základe týchto zistení potom vytváram správu pre klienta. Najdôležitejšia časť je vynulovanie session – čo v tomto prípade znamená vyprázdnenie košíka. To by bolo asi tak všetko.

Účelom tohto článku bolo hlavne ukázať čitateľovi niečo z praktického využitia session. Keďže session tracking sa spravidla zabezpečuje cez cookies, ktoré môžu byť zakázané, chcel som ukázať aj spôsob, ako sa s tým môže programátor vysporiadať. Príklad si môžete stiahnuť.

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