VÝVOJ PODNIKOVÝCH APLIKACÍ NA PLATFORMĚ JAVA EE Zbyněk Šlajchrt Část 2.
Protokol HTTP - Princip Webový server Odpověď Dotaz 2 Webová aplikace
Protokol HTTP Request-response protokol (nebo také client-server) Původně navržen na přenos hypertextových dokumentů – HTML (Tim-Berners Lee) Aktuální verze 1.1 – lepší správa připojení k serveru Obvykle provozován nad TCP/IP, není však podmínkou Dokumenty jsou identifikovány URI – Uniform Resource Identifier Typickým klientem je webový prohlížeč 3
Protokol HTTP Bezstavový protokol Server neví, zda zpracovávaný dotaz souvisí s předchozím "Stavovost" řeší aplikace pomocí cookies (default) či tzv. přepisování URL (údaje o relaci jsou serverem zakódovány do všech URL v HTML dokumentu) Původně navržen ke stažení jednoho dokumentu v rámci jednoho připojení Výhody: jednoduchost, minimální zátěž síťě Nevýhody: absence konverzačního kontextu 4
HTTP Request - příklad GET /en/html/dummy.php HTTP/1.1 Host: User-Agent: Mozilla/5.0 Accept: text/xml,text/html;text/plain;image/png Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO ,utf-8 Connection: keep-alive Referer: 5
HTTP Request Skládá se ze třech částí Řádka dotazu na dokument (Request line) HTTP/ GET /mypage.html HTTP/1.1 Hlavičky – různorodé doplňující informace Např. Accept-Language: en Tělo zprávy (nepovinné) Obsahuje data odeslané metodou POST Často pole formuláře, nahrávaný soubor, SOAP XML 6
Metody dotazování - základní GET (idempotent - should) požaduje reprezentaci specifikovaného zdroje neměla by mít vedlejší efekt! (tzv. idempotence) POST odesílá data z klienta na server ke zpracování je určena k modifikaci stavu odkazovaného zdroje PUT (idempotent - must) zakládá nový zdroj v aplikaci DELETE (idempotent - must) odstraňuje zdroj z aplikace 7
Metody dotazování - pokračování HEAD (idempotent - should) Jako GET, server však vrací pouze hlavičky bez těla TRACE (idempotent - should) server vrací příchozí dotaz jako tělo odpovědi kontrola modifikace dotazu mezilehlými servery OPTIONS (idempotent - should) vrací seznam metod podporovaných serverem pro specifikovaný zdroj CONNECT otevře transparentní TCP/IP tunel pro SSL komunikaci 8
HTTP Response - příklad HTTP/ OK Date: Wed, 16 Aug 2000, 13:25:54 GMT Server: NCSA/1.5.2 Last-modified: Sat, 22 Jan 2000, 05:15:43 Content-type: text/html Content-length: Hello! 9
HTTP Response Odpověď se skládá ze tří částí: Řádka se stavovým kódem HTTP/ HTTP/ OK HTTP/ Not Found Možnost customizace Hlavičky odpovědi Informace o serveru a obsahu odeslaném na klienta Kódování, MIME typ, datum poslední změny atp. Tělo odpovědi Vlastní data 10
Stavové kódy 1xx – informační 100 Continue – výzva klientovi, aby poslal další data 2xx – úspěch 200 OK – standardní odezva úspěšných dotazů 3xx – přesměrování 303 See Other – přesměrování pomocí GET 4xx – chyba u klienta 401 Unauthorized – neautorizovaný přístup 418 I'm a teapot - 5xx – chyba na serveru 503 Service Unavailable – server je nedostupný 11
Webová aplikace v Javě Webový server Servletový kontejner Servlet1 Servlet2 odpověď dotaz 12
Co je servlet? Javovská komponenta spravovaná kontejnerem, která generuje dynamický obsah. Servlety jsou standardní Java třídy Interagují s klienty prostřednictvím request/response paradigmatu Analogie k CGI skriptům Servlety jsou obecně mnohem výkonnější (vlákna) Oddělení logiky aplikace od systémových operací Servlet API Serv let1
Co je servletový kontejner? Součást webového nebo aplikačního serveru Poskytuje síťové služby pro příjímání a dekódování dotazů odesílání a zakódování odpovědí správa životního cyklu servletů bezpečnostní aspekty (ověření identity, autorizace) Default je HTTP protokol může podporovat HTTPS (HTTP over SSL) Musí implementovat HTTP 1.0 i HTTP
Typický servlet 15
Příklad HTTP komunikace 1. Prohlížeč odešle HTTP dotaz na webový server 2. Webový server předá dotaz kontejneru. Ten může běžet ve stejném procesu, jako server, ale i jinde. 3. Kontejner určí na základě konfigurace servlet pro předání požadavku 4. Servlet zpracuje parametry a hlavičky dotazu a vygeneruje odpověď 5. Kontejner ověří, že dotaz je správně uzavřen a předá řízení webovému serveru 16
Rozhraní servletu javax.servlet.Servlet Základní rozhraní pro všechny servlety Principiální metoda service obsluha příchozích požadavků a generování odpovědi Dvě abstraktní implementace javax.servlet.GenericServlet základ pro různé protokolově závislé implementace javax.servlet.http.HttpServlet dědí z GenericServlet nejčastěji používaná implementace 17
Rozhraní servletu 18 javax.servlet.Servlet > javax.servlet.Servlet > javax.servlet.GenericServlet > javax.servlet.GenericServlet > javax.servlet.http.HttpServlet > javax.servlet.http.HttpServlet > cz.vse.javaee.SampleServlet
Metody pro obsluhu HTTP dotazu HttpServlet implementuje metodu service jako šablonovou metodu (GoF – Template Method) Příchozí požadavek deleguje na jednu z řady prázdných metod podle metody odeslání HTTP dotazu doGet doPost doPut atd... Ve většině případů se používají pouze doGet a doPost 19
Podpora podmíněného GET Zabraňuje zbytečnému přenosu dat po síti Klient říká: "Pošli mi data pouze pokud byl zdroj modifikován od datumu, který ti posílám v hlavičce If- Modified-Since." Pozn.: Kromě této hlavičky existují i další: If-Unmodified- Since, If-Match, If-None-Match, or If-Range Metoda getLastModified vrací čas poslední modifikace požadovaného zdroje Návratová hodnota se použije v implementaci podmíněného GET v třídě HttpServlet. 20
Instance servletu Kontejner vytváří vždy právě jednu instanci servletu na jednu jeho deklaraci Deklarace je uvedena v deployment deskriptoru anotací Výjimkou je Distribuované prostředí (clustery) Single Thread Model servletu kontejner může vytvářet více instancí při velkém zatížení 21
Single Thread Model servletu Deprecated Implementací SingleThreadModel značkovacího rozhraní je zaručeno, že metoda service bude vždy běžet pouze v jednom vlákně. Tato vlastnost má velmi neblahý vliv na výkon serveru, proto se velmi nedoporučuje Servlety musí jinak počítat s tím, že metoda obsluha dotazu bude prováděna ve více vláknech Pečlivě synchronizovat přístupy kódu k atributům! 22
Životní cyklus servletu Definuje, jak je servlet vytvářen, inicializován, používán k obsluze požadavků a ukončován. Životní cyklus je vyjádřen v rozhraní Servlet metodami init voláno při inicializaci servletu service voláno při obsluze požadavku klienta destroy voláno, když má být servlet zrušen 23
Inicializace servletu Probíhá před vlastním zpracováním požadavků Účelem je např.: Načíst konfigurační parametry Inicializovat jednorázová náročná připojení k jiným systémům Různé jednorázové akce Kontejner volá na servletu metodu void init(javax.servlet.ServletConfig servletConfig) throws javax.servlet.ServletException; Předává se konfigurační objekt, který nese informace o konfiguraci servletu ve formě párů jméno-hodnota 24
Konfigurace servletu 25
Načtení konfigurace 26
Přehled metod ServletConfig getInitParameter(name) vrací hodnotu parametru getInitParameterNames() vrací enumeraci názvů parametrů getServletContext() vrací instanci aplikačního kontextu getServletName() vrací název servletu 27
Zpracování požadavků Probíhá v metodě servletu service(ServletRequest request, ServletRequest response) throws ServletException, IOException Kontejner zapouzdří dotaz do objektu ServletRequest Servlet generuje odpověď prostřednictvím objektu ServletResponse Pro každé volání je vytvářena nová dvojice těchto objektů 28
Zpracování HTTP požadavků Probíhá v metodách doGet doPost a dalších, nazvaných analogicky (doPut, atp.) Jako parametry jsou předávány objekty reprezentující dotaz a odpověď HttpServletRequest HttpServletResponse 29
Zpracování ve více vláknech Kontejner může volat metodu service souběžně ve více vláknech Je třeba korektně synchronizovat přístupy ke sdíleným datům Takto ne!!! protected synchronized void doGet(...) Velmi negativní dopad na výkonnost serveru V podstatě analogické SingleThreadModelu 30
Zpracování ve více vláknech Operace ++ není atomická Přičtení a použití počítadla musí být atomické 31
Zpracování ve více vláknech Správně 32
Vyhazování výjimek Servlet může vyhazovat dvě výjimky ServletException signalizuje chybu ve zpracování požadavku kontejner provede čistící aktivity aplikační chyby – instance servletu zůstává v činnosti UnavailableException signalizuje, že servlet není schopen dočasně či permanentně zpracovat požadavek – metoda isPermanent na výjimce permanentní problém vede k odstranění instance servletu – volá se destroy – vrací se stavový kód 404 (Not Found) dočasný vede k 503 (Service Unavailable) po dobu trvání problému – metoda getUnavailableSeconds na výjimce 33
Asynchronní zpracování Novinka v Java EE 6 Stává se, že servlet musí čekat na odpověď od např. webové služby či JDBC připojení Počet vláken je velmi omezený – thread pool velikost řádově jako počet procesorů či jader Čekání zbytečně blokuje vlákno, které by mohlo obsluhovat jiné požadavky Servlet 3.0 umožňuje, aby se obslužné vlákno vrátilo do poolu, přičemž zpracování požadavku si převezme jiné vlákno či callback 34
Diagram asynchronního zpracování 35
Ukončení obsluhy zpráv servletem Kontejner se může kdykoliv rozhodnout, že odstraní servlet Volá na servletu metodu destroy V této metod servlet uvolňuje všechny prostředky systému, které využíval Kontejner musí nechat doběhnout všechna vlákna, ve kterých běží metoda service Poté je objekt servletu k dispozici garbage collectoru 36
HTTP Request Zapouzdřuje veškeré informace získané z dotazu Parametry Atributy Hlavičky Cestu Cookies SSL atributy Locale Encoding 37
Parametry v GET dotazu GET /index.html?userid=joe&password=guessme HTTP/1.1 Host: User-Agent: Mozilla/4.0 38
Parametry v POST dotazu POST /login.jsp HTTP/1.1 Host: User-Agent: Mozilla/4.0 Content-Length: 27 Content-Type: application/x-www-form-urlencoded userid=joe&password=guessme 39
Parametry dotazu Předávány klientem jako řetězce v HTTP dotazu typicky pole formulářů Uchovávány jako páry klíč-hodnota vícenásobný výskyt možný V případě GET metody jsou v URL (za ?) Parametry jsou kontejnerem načteny ze vstupního proudu (socketu) pouze tehdy, když: HTTP metoda je POST typ obsahu je application/x-www-form-urlencoded servlet zavolal na počátku zpracování jednu z metod: getParameterXXX metody 40
Parametry dotazu Pokud uvedené podmínky nejsou splněny, POST data jsou stále ve vstupním proudu. 41
File upload Dotaz má typ obsahu multipart/form-data Servlet musí být Objekt dotazu zpřístupní metody Collection getParts() Part getPart(String name) Třída Part reprezentuje jeden soubor posílaný na server getInputStream, getContentType, getName, getSize... 42
Atributy Atributy jsou objekty asociované s dotazem Mohou být nastaveny kontejnerem, ale i servletem Nesou informace, které nejsou v API Mohou sloužit pro komunikaci mezi servlety v rámci jednoho dotazu Metody getAttribute, getAttributeNames, setAttribute Klíče atributů, které začínají na java, javax, sun, com.sun jsou rezervované 43
Hlavičky Objekt dotazu obsahuje také hlavičky z HTTP dotazu Seznam na Metody getHeader, getHeaders, getHeaderNames getIntHeader, getDateHeader 44
Cesty v dotazu Cesta v dotazu je složena z několika částí Context Path - getContextPath prefix asociovaný s kontextem aplikace (servlet kontext) Servlet Path - getServletPath Část cesty, která odpovídá mapování servletu PathInfo - getPathInfo Zbytek cesty, která není ani Context Path ani Servlet Path 45
Cookies Metoda getCookies na HttpServletRequest vrací seznam cookies obsažených v dotazu Cookies se posílají s každým dotazem Jsou to páry klíč-hodnota s dobou platnosti, po kterou mají být uchovány u klienta Na klienta se posílají prostřednictvím metody HttpServletResponse.addCookie(Cookie) 46
Internacionalizace I18N Klient může indikovat, ve kterém jazyce si přeje komunikovat Metody getLocale preferované jazykové prostředí getLocales seznam jazykových prostředí seřazených podle priority 47
ServletContext Představuje prostředí aplikace, ve které servlet běží Pomocí tohoto objektu může servlet logovat události získávat URL k prostředkům číst konfigurační parametry celé aplikace nastavovat a číst atributy sdílené napříč aplikací Vrací ho metoda servletu getServletContext 48
ServletContext - konfigurace Konfigurace v souboru WEB-INF/web.xml 49
Užitečné metody v ServletContext getInitParameter setAttribute, getAttribute, getAttributeNames, removeAttribute getResource, getResourceAsStream, getRealPath log getRequestDispatcher popis viz JavaDoc k Java EE 6 50
HTTP Response Zapouzdřuje veškeré informace, které se mají poslat na klienta, tj. hlavičky + tělo Skupiny metod Buffering řízení vyrovnávací paměti, ve které se uchovává odpověď Hlavičky a cookies metody pro nastavování hlaviček a cookies v odpovědi Usnadnění sendRedirect, sendError I18N setLocale 51
Filtry Filtry jsou komponenty, které umožňují transformovat data přicházející k servletu a odcházející ke klientovi Přiřazují buď přímo k servletu v konfiguraci web.xml Nebo se vážou k nějaké URI Příklady: autentikační filtry logovací a auditní filtry konverzní filtry komprimační/dekomprimační filtry 52
Filtry - interakce servlet filtr2 filtr1 53
Filter - implementace 54
Filtry – konfigurace ve web.xml 55
Sessions HTTP je bezstavový protokol Často je nutné, aby aplikace rozpoznala dotazy, které patří stejnému klientovi potřebujeme tedy tzv. konverzační kontext stavová funkce Session – sezení, relace Session tracking mechanismy Cookies – JSESSIONID cookie udržuje ID session SSL Sessions – SSL již obsahuje takový mechanismus URL Rewriting – používá se, když klient odmítá cookies 56
Vytváření session Metody v HttpServletRequets HttpSession getSession() Vrací aktuální session, nebo vytváří novou, pokud neexistuje. HttpSession getSession(boolean create) Vrací aktuální session. Parametr create určuje, zda se bude vytvářet nová session v případě, že ještě neexistuje. Často je třeba zjistit, že se jedná o novou session boolean HttpSession::isNew() Aplikace musí počítat se situací, že klient odmítne přidružit se k session 57
Důležité metody HttpSession get/set/removeAttribute, getAttributeNames operace s atributy – páry (klíč, hodnota) takto lze sdílet data napříč aplikací v rámci session invalidate zneplatňuje session a odpojí všechny hodnoty atributů setMaxInactiveInterval specifikuje interval mezi dotazy, po jehož překročení kontejner zneplatní session getId vrací jednoznačné ID session 58