Vývoj programových systémů v jazyce Java


Obsah

1. Úvod do předmětu, průběh, kritéria hodnocení. Architektury rozsáhlých aplikací.
Charakteristika a cíle předmětu a průběh výuky
Charakteristika
Průběh výuky
Úlohy
Projekty
Zkouška
Složky hodnocení
Kritéria hodnocení předmětu
Modely
Modely vícevrstvých aplikací
Vrstvy
Komponenty
Orientace na služby
Správa
Zabezpečení
Kontejnery a rámce
Komponentní vs. objektové programování
Objektové programování - principy
Objektové programování - terminologie
Objektové programování - přednosti
Objektové programování - nedostatky
Komponentní programování - principy
Co musí komponenta splňovat
Srovnání komponentního a objektového přístupu
Komponentní programování - výhody oproti OOP
Komponentní programování - souvislosti
Komponentní dokumenty
Architektury orientované na služby (Service-oriented Architectures - SOA)
Motivace k SOA
Definice SOA
Technologie SOA
Charakteristiky SOA
Vztah komponent a služeb
Odkazy
2. Metodiky vývoje - Agilní a extrémní programování. Nástroje správy vývoje a nasazení SW.
Agilní programování
Co je Agilní programování
Manifesto for Agile Software Development
Motivace
Principy
Zásada - stálý kontakt se zákazníkem - zadavatelem
Zásada - časté uvolňování funkčního SW
Zásada - vysoká kvalita
Zásada - netvořit do zásoby
Extremní programování (Extreme Programming, XP)
Motivace pro Extreme Programming (XP)
Co je XP
Charakteristika XP
Východiska řízení týmu podle XP
Hlavní zásady XP
Vedlejší zásady XP
Vývojové činnosti XP
Hlavní techniky XP
Fáze XP projektu
KISS (Keep It Simple, Stupid)
Princip KISS
Zásada - navrhovat jednoduše
Zásada - netvořit do zásoby
Refaktoring
Refaktoring - proč
Refaktoring - metody
Refaktoring - nástroje kom.
Refaktoring - nástroje o-s
Programování řízené testy (Test-drive Development, TDD)
Motivace
Principy
Kde nelze testovat?
Generický postup TDD
Odkazy
Systémy správy verzí
Motivace
Principy
Klasická řešení - RCS a CVS
Typické příkazy správy verzí
Klienti
Pro co se systémy nehodí?
Subversion
Subversion - klient Tortoise pro Windows
Tortoise -- vzdálený přístup
Správa sestavování - Ant
Charakteristika
Motivace
Struktura projektu
Příklad 1
Závislosti
Příklad 2
Maven
Motivace
Maven - charakteristika
Project Object Model (POM)
Projekt v Mavenu
Maven repository
Instalace a nastavení
Příklad POM (project.xml)
Příklad POM - pokračování
Struktura POM obecně
Proměnné (properties) v POM
Struktura repository
Cíle v Mavenu
Maven Plugins
Často používané cíle
Vytvoření projektu
Reporting
Rozšíření možností Mavenu
3. Webové aplikace.
3. Datová vrstva javových aplikací - zajištění perzistence a správy dat. JBDC, JDO, Hibernate.
Java Database Connectivity (JDBC)
Co je JDBC
Postup práce s JDBC
Hlavní třídy (komponenty) JDBC
Hlavní třídy (komponenty) JDBC (2)
Příklad - zavedení ovladače DBMS
Příklad - vytvoření spojení, příkazu a jeho spuštění
Charakteristika JDBC rozhraní
JDBC rozhraní - balíky
Práce s databází
Transakce
Transakce - příklad
Demo - HSQLDB
HSQLDB - režimy práce
Předpřipravené příkazy
Předpřipravené příkazy - příklad
Uložené procedury
Modifikovatelné výsledky dotazu
Metadata
Zpřístupnění datového zdroje přes JNDI
Java Data Objects (JDO)
JDO - charakteristika
JDO - forma
JDO - motivace
JDO - struktura
JDO - implementace
JDO - informační zdroje
JDO - alternativy
Serializace dat do XML
Serializace obecně - připomenutí
Serializace
Serializace - metody
Serializace do XML - vazba XML na Javu
Jednoduché nástroje serializace - XStream
Jak funguje XStream
XStream - příklad, krok 1
XStream - příklad, krok 2
Hibernate
Hibernate
4. Aplikační vrstva javových aplikací - řízení toku, správa komponent. Pokročilé zásady a metodiky návrhu aplikační logiky - Design by Contract, Inversion of Control, Aspect-oriented Programming. Kontejnery, aplikační servery.
Aplikační vrstva javových aplikací
Aplikační vrstva javových aplikací
Design by Contract
Design by Contract - návrh podle kontraktu
DBC - jak dosáhnout
DBC - nástroj jass
Postup při práci s jass
Odkazy
Inversion of Control (IoC)
Nezbytné pojmy z komponentních systémů
IoC - Motivace
Tradiční řízení životního cyklu komponent
IoC - Hlavní princip
IoC - Možné podoby
Interface Injection
Setter Injection - komponenta
Setter Injection - popis komponenty
Setter Injection - výhody/nevýhody
Constructor Injection
Constructor Injection - příklad komponenty
Použití IoC - kontejnery
Aspect Oriented Programming (AOP)
AOP - Motivace
AOP - Motivační příklad
AOP - Principy
Kontejnery a aplikační servery
Kontejnery a aplikační servery
Java Management extension (JMX)
Co je JMX
Co řídí JMX
Principy JMX
Který objekt (komponentu) jako JMX?
Úrovně JMX modelu
Ovládané zdroje
Jak se zdroje ovládají
MBean
Co obsahují/zpřístupňují rozhraní MBean
Typy MBean
Aplikační rámec Tammi - případová studie
Charakteristika Tammi
Příklad jednoduché komponenty typu MBean
Skriptování v javovém prostředí - BSF
Co je skriptování?
Proč skriptovat?
Proč skriptovat právě teď?
Bean Scripting Framework
BSF - co nabízí
BSF - typické použití
BSF - download a další info
Skriptování v javovém prostředí - Groovy
Groovy - motivace
Stažení
Instalace
Spuštění
Příklad - iterace
Příklad - mapa
Příklad - switch
Řízení a sledování aplikací - protokolování
Protokolování (logging)
Protokolování - výhody
Protokolování - možnosti v Javě
Protokolování - API
Protokolování - příklad
5. Prezentační vrstva javových webových aplikací. Přístupy - šablony, dekorátory. Velocity, WebMacro, Sitemesh, Freemarker. Nové přístupy - AJAX
Prezentační vrstva webových aplikací
Prezentační vrstva webových aplikací
AJAX - Asynchronous JavaScript and XML
Webové aplikace - důvody pro
Webové aplikace - důvody proti
Přístup AJAX - Asynchronous JavaScript and XML
Výhody
Kde je použito?
Jak pracuje?
AJAX ve spojení s J2EE
6. Komplexní podpora webových aplikací. Webové rámce.
Webové aplikační rámce
Osnova
Webový rámec
Třívrstvá architektura
Koncepce MVC
Přednosti MVC
Javové webové aplikace
Javové webové aplikace
Javové webové aplikace (2)
Javové webové aplikace (3)
Javové webové kontejnery
Funkcionalita webových rámců
Oddělení prezentační vrstvy
Oddělení prezentační vrstvy (2)
Oddělení prezentační vrstvy (3)
Funkcionalita webových rámců
Správa zabezpečení - příklad
Validace uživatelských vstupů
Udržování informací o relaci
Řízení toku aplikace
Příklad řízení toku - Struts
Zotavení z chyb
Záznamy o událostech (logging)
Internacionalizace a lokalizace
Internacionalizace a lokalizace - příklad
Zajištění perzistence objektů
Škálovatelnost a distribuovanost
Škálovatelnost a distribuovanost
Podpora vývojovými prostředími
Přehled rámců
Shrnutí
7. Enterprise JavaBeans
Enterprise JavaBeans
Enterprise JavaBeans
8. Systémy řízení zpráv, Java Messaging Service (JMS) API
Systémy řízení zpráv, Java Messaging Service (JMS) API
Systémy řízení zpráv - motivace
Systémy řízení zpráv - výhody
Systémy řízení zpráv - principy
Systémy řízení zpráv - standardy
JMS - kdy použít?
JMS - co nabízí
JMS - architektura
JMS - domény
Point-to-point Messaging
Publish/Subscribe
Komponenty JMS API
Zpracování zprávy
Demo JMS s použitím Sun Java System Message Queue
Použití Sun Java System Message Queue
Co je třeba pro překlad klienta
Spuštění serveru (Message Brokeru)
Test běhu SJSMQ
Kostra jednoduché aplikace
9. Webové služby
Webové služby
Webové služby
Webové služby typu REST
Motivace
Co je REST
Principy
Co REST aplikace používají
Charakteristika REST služeb
Co rozmyslet před návrhem REST služby
Postup návrhu

Seznam obrázků

31..1. Použití servletu
31..2. Životní cyklus servletu
8.1. Spolupráce JMS a JNDI (z tutoriálu J2EE Sun)
8.2. Mechanizmus Point-to-Point (z tutoriálu J2EE Sun)
8.3. Mechanizmus Publlish/Subcscribe (z tutoriálu J2EE Sun)
8.4. Programovací model JMS API (z tutoriálu J2EE Sun)
8.5. Spuštění SJS Message Queue
8.6. Test běhu SJS MQ

Seznam příkladů

31..1. HelloClientServlet.java
32..1. web.xml
32..2. build.properties

Kapitola 1. Úvod do předmětu, průběh, kritéria hodnocení. Architektury rozsáhlých aplikací.

Charakteristika a cíle předmětu a průběh výuky

Charakteristika

Předmět PA165 Vývoj programových systémů v jazyce Java je magisterským předmětem určeným pro zájemce o hlubší proniknutí do principů výstavby rozsáhlejších programových systémů na platformě Java.

Cílem je seznámit s principy:

  • kvalitního návrhu rozsáhlých systémů (jak navrhnout architekturu, jakou zvolit infrastrukturu/rámec...),

  • jejich tvorby (jaké zásady, nástroje,...)

  • testování (při vývoji, zavádění a v provozu),

  • refaktoringu (=zlepšování kódu bez změny funkcionality),

  • ladění výkonu (optimalizace)

Průběh výuky

Výuka probíhá jako:

  • Dvouhodinová přednáška - Po od 14.00 v A107

  • Dvouhodinová cvičení v nové učebně B130 (v přízemí "za halou")

  • Nedílnou součástí je řešení projektu - ve cvičení s možností konzultací nebo ve volném čase

Úlohy

Těžištěm předmětu je samostatná práce na projektech. Společně zadávaných úloh je proto minimum.

Projekty

Projekty jsou koncipovány jako týmové (4členné týmy).

Tematicky vždy pokrývají netriviální část z celkového obsahového záběru předmětu a musí tomu být i technologicky přizpůsobeny.

Zadání projektu stanovuje nebo schvaluje cvičící.

Zkouška

Zkouška bude ústní.

Student při ní musí prokázat dobrý přehled ve studované problematice s tím, že principy a technologie, které aplikoval při řešení projektu musí zvládnout do větší hloubky.

Složky hodnocení

Hodnocení předmětu je stanoveno podle celkového součtu bodů z jednotlivých kritérií:

  • Úlohy - 15 bodů

  • Projekt - 50 bodů

  • Ústní zkouška - 35 bodů

Kritéria hodnocení předmětu

K ukončení zkouškou potřebujete:

  • A 94 - 100 bodů

  • B 88 - 93 bodů

  • C 82 - 87 bodů

  • D 76 - 81 bodů

  • E 70 - 75 bodů

  • F 0 - 69 bodů

K ukončení zápočtem potřebujete:

  • 60 bodů

Modely

Modely vícevrstvých aplikací

Vrstvy

Komponenty

Orientace na služby

Správa

Zabezpečení

Kontejnery a rámce

Komponentní vs. objektové programování

Objektové programování - principy

Obecné, známé principy OO jazyků:

  • možnost (a nutnost) zapouzdření dat a metod ned nimi pracujících do podoby objektu,

  • dědičnost (inheritance) - odvozování nových typů s děděním vlastností typů rodičovských,

  • polymorfizmus (mnohotvarost) - využitelnost objektů poděděných typů v roli předků

Objektové programování - terminologie

Na obecných principech OOP není mezi teoretiky a vývojáři (v různých jazycích) až taková shoda, jak by se mohlo zdát:

  • bezespornou charakteristikou OOP je zapouzdření,

  • další char. jako dědičnost (inheritance) je už v různých jazycích pojímána různě, příp. chybí - a přesto můžeme ještě hovořit o OO jazyku,

  • polymorfizmus (mnohotvarost)

Objektové programování - přednosti

Výhody OOP (za předpokladu kvalitního návrhu) jsou dobře známy:

  • dobrá čitelnost a udržovatelnost kódu,

  • rozšiřitelnost,

  • určitá vnitřní nahraditelnost částí - např. třídu lze nahradit potomkem

  • aspoň teoreticky - využitelnost i jako "black-box"/černá skříňka - bez znalosti zdrojového kódu

Objektové programování - nedostatky

Ale tak skvělé to zase není:

  • bez zdrojového kódu lze dobře znovupoužít jen kvalitní objektový kód,

  • kód je znovupoužitelný většinou jen na mikroúrovni - jednotlivé třídy

  • k znovupoužití je třeba detailní znalosti celého prostředí programu, rozhraní větších programů bývá většinou komplikované - i proto, že komponenty (objekty) jsou příliš malé, jemné

Komponentní programování - principy

V zásadě vychází z objektového, ale:

  • komponenty jsou VELKÉ (coarse-grained) objekty zapouzdřující ucelený kus aplikační logiky nebo dat,

  • komponenty jsou nezřídka přístupné i vzdáleně (tj. po síti, často i z jiných platforem/jazyků),

  • komponenty mohou (za podpory middleware) existovat relativně samostatně

  • vazby k ostatním jsou dobře kontrolovatelné a obecně spíše volné

  • jako protokoly, datové formáty atd. jsou přednostně použity standardní, byť třeba ne tak efektivní

Co musí komponenta splňovat

Komponenta musí být:

  • dobře dokumentovaná, s jasně definovaným API, nejlépe i formálně

  • důkladně testovaná

  • robustní a odolná vůči chybám uživatele (validace vstupů)

  • musí mít podrobné hlášení chyb

  • musí se chovat defenzivně - být odolná vůči nesprávnému použití - je nutné s ním počítat

Srovnání komponentního a objektového přístupu

Přestože komponenty jsou ve většině případů realizovány jako objekty - a tedy komponentní programování je v zásadě pokračováním objektového - je tu jeden zásadní rozdíl.

  • Při návrhu objektů v podstatě přímočaře reprezentujeme strukturu a chování výseku reality.

    Předpokládá se soulad chápání koncového uživatele (zákazníka) a návrháře ohledně této reprezentace.

  • Návrh komponent naproti tomu zcela podřizujeme účelu, proč komponenta existuje, a znovupoužitelnosti.

    Vnitřní struktura uživatele (zákazníka) nezajímá.

Komponentní programování - výhody oproti OOP

Oproti OOP to umožňuje:

  • daleko lepší znovupoužitelnost - slabší vazby, vyšší autonomie

  • vyšší robustnost komponentních systémů

  • snazší vyměnitelnost (nefunkční, zastaralé) komponenty

  • možnost souběžného použití různých verzí komponent

  • lepší testovatelnost komponent vzhledem ke slabším vazbám

  • vývoj mohou dělat nezávislejší mikro-týmy

Komponentní programování - souvislosti

V javovém světě jsou minimálně tyto trendy a možnosti odpovídající KP:

  • pro výstavbu velkých systémů (aplikací) se používají Enterprise JavaBeans,

  • existují tzv. aplikační servery, které pro ně zajišťují middleware,

Komponentní dokumenty

Komponentní principy nejsou užívány jen při tvorbě SW, ale i návrh struktur dokumentů:

Architektury orientované na služby (Service-oriented Architectures - SOA)

Motivace k SOA

  • Obecný příklon k chápání IT jako poskytovatele služby - servisu - nikoli jen technologie.

  • Stejně se začíná přistupovat i k vazbě mezi SW komponentami.

  • Orientace na služby se ve vývoji SW stává vůdčím směrem.

Definice SOA

Architektury orientované na služby (Service-oriented Architectures - SOA) představují princip budování softwarových architektur založený na:

  • komponentách umístěných v uzlech sítě

  • nabízející své služby ostatním prostřednictvím dobře definovaného protokolu

  • služby jsou bezestavové

  • vnitřní realizace klienta obvykle nezajímá - standardy zajišťují interoperabilitu služeb

Technologie SOA

SOA v zásadě neváže na žádnou SW platformu, OS, pg. jazyk ani konkrétní standard.

V úzkém slova smyslu se za SOA dnes někdy považují architektury budované na tzv. Web Services (webových službách, WS) kolem množiny standardů:

  • XML - data reprezentovaná značkovanými dokumenty

  • HTTP jako základní webový protokol

  • SOAP - jako std. protokol WS

  • WSDL - popisovač webových aplikací

  • UDDI - služby registrace a vyhledávání webových služeb

Charakteristiky SOA

Orientace na služby přináší:

  1. Nahraditelnost služeb

  2. Interoperabilitu

  3. Možnost nezávislého ladění služeb

  4. Usnadňuje integraci systémů třetích stran.

Vztah komponent a služeb

Oboje jsou moderní až módní záležitosti, vztah lze definovat takto:

  • Komponenta je často entitou realizující určitou službu.

  • Koncový uživatel nahlíží více na služby, zatímco vývojáře zajímají rovněž komponenty, které je realizují.

Kapitola 2. Metodiky vývoje - Agilní a extrémní programování. Nástroje správy vývoje a nasazení SW.

Obsah

Agilní programování
Co je Agilní programování
Manifesto for Agile Software Development
Motivace
Principy
Zásada - stálý kontakt se zákazníkem - zadavatelem
Zásada - časté uvolňování funkčního SW
Zásada - vysoká kvalita
Zásada - netvořit do zásoby
Extremní programování (Extreme Programming, XP)
Motivace pro Extreme Programming (XP)
Co je XP
Charakteristika XP
Východiska řízení týmu podle XP
Hlavní zásady XP
Vedlejší zásady XP
Vývojové činnosti XP
Hlavní techniky XP
Fáze XP projektu
KISS (Keep It Simple, Stupid)
Princip KISS
Zásada - navrhovat jednoduše
Zásada - netvořit do zásoby
Refaktoring
Refaktoring - proč
Refaktoring - metody
Refaktoring - nástroje kom.
Refaktoring - nástroje o-s
Programování řízené testy (Test-drive Development, TDD)
Motivace
Principy
Kde nelze testovat?
Generický postup TDD
Odkazy
Systémy správy verzí
Motivace
Principy
Klasická řešení - RCS a CVS
Typické příkazy správy verzí
Klienti
Pro co se systémy nehodí?
Subversion
Subversion - klient Tortoise pro Windows
Tortoise -- vzdálený přístup
Správa sestavování - Ant
Charakteristika
Motivace
Struktura projektu
Příklad 1
Závislosti
Příklad 2
Maven
Motivace
Maven - charakteristika
Project Object Model (POM)
Projekt v Mavenu
Maven repository
Instalace a nastavení
Příklad POM (project.xml)
Příklad POM - pokračování
Struktura POM obecně
Proměnné (properties) v POM
Struktura repository
Cíle v Mavenu
Maven Plugins
Často používané cíle
Vytvoření projektu
Reporting
Rozšíření možností Mavenu

Agilní programování

Co je Agilní programování

Agilní programování (Agile Programming, AP) je relativně novým přístupem k vývoji software.

  • Není to jedna metodika, přesný návod, jak systém navrhnout a realizovat.

  • Je to spíše přístup, "filozofie", do které je třeba dodat konkrétní postupy pro jednotlivé úkony vývoje.

  • Označení Agilní programování bylo poprvé zavedeno skupinou autoritativních odborníků (praktiků) na SW metodiky.

  • Zastánci AP se sdružili při sestavení manifestu AP, formulující jeho hlavní zásady.

Manifesto for Agile Software Development

We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value:

Individuals and interactions over processes and tools

Working software over comprehensive documentation

Customer collaboration over contract negotiation

Responding to change over following a plan

That is, while there is value in the items on the right, we value the items on the left more.

Motivace

Motivací pro AP byla především řada neúspěchů při budování rozsáhlých softwarových děl a řízení realizačních projektů.

  • Projekty trvaly déle, než se předpokládalo.

  • Stály více peněz.

  • Objevovala se negativa typu "hraní na úspěch/výsledek" a nikoli výsledek sám.

  • K cíli se nešlo přímočaře, produkovaly se dále nevyužité (nevyužitelné) artefakty, věci do zásoby.

  • Mezi zadavatelem (zákazníkem) a tvůrcem byla propast (formalizmus místo spolupráce).

  • Vytvořené produkty pak často neodpovídaly aktuální potřebě...

Principy

  • Realizovat věci nejjednodušším možným způsobem.

  • Tak se předejde nadměrné složitosti vytvářeného artefaktu.

  • Je větší šance, že produkt bude bez chyb.

  • Vynakládání prostředků lze při dodržení této zásady lépe kontrolovat.

Zásada - stálý kontakt se zákazníkem - zadavatelem

Namísto jednorázového (obvykle složitého) jednání o smlouvách s přesnou (a v podstatě statickou) specifikací zadání:

  • Zákazník (budoucí uživatel) je ve stálém, nejlépe denním a osobním kontaktu s vývojářem.

  • Takové dynamické týmy musejí být dobře motivované, nehrát si na úspěch, ale musejí o něj stát.

Zásada - časté uvolňování funkčního SW

  • Zákazník často dostává nové verze (měsíčně, ještě lépe týdně), ihned konfrontuje stav s požadavky, hledá chyby...

Zásada - vysoká kvalita

  • Technická kvalita je základem. Neváhá se kvůli tomu podstoupit i radikální refaktoring kódu.

Zásada - netvořit do zásoby

  • Nemá se tvořit (programovat) "dopředu", "do zásoby".

  • Ze zkušeností totiž vyplývá, že takové artefakty obvykle už nepoužijeme.

Extremní programování (Extreme Programming, XP)

Motivace pro Extreme Programming (XP)

Na vývoj software má vliv mnoho faktorů, které se neustále mění (zadání, návrh, technologie, trh, složení týmu apod.). Obecně lze říci, že změna je jedinou konstantou vývoje software. Problémem vývoje softwaru je schopnost úspěšného zvládnutí těchto změn za přijatelné náklady.

  • Toto je východisko pro řadu moderních metodik programování (řízení SW projektů), které se souhrnně označují jako agile programming.

  • Mezi ně patří i Extreme Programming (XP).

Co je XP

Viz J. Ministr, IT pro praxi, 2004:

  • Extrémní programování (XP) je metodika vývoje softwaru, která je postavena na tvorbě zdrojového textu v týmech, jež tvoří dva až deset programátorů. XP používá obecně známé principy a postupy vývoje softwaru, tyto však dotahuje do extrémů.

Charakteristika XP

Od ostatních metodik se XP odlišuje v následujících vlastnostech:

Automatizované testování

testy jsou tvořeny před samotnou tvorbou zdrojového textu za účelem následného ověření skutečného pokroku ve vývoji softwaru z hlediska jeho požadované funkcionality (testy navrhuje zákazník) a architektury programového modulu (testy navrhuje programátor).

Verbální komunikace

společně s testy a zdrojovým textem slouží ke sdělování systémové struktury a záměru projektu.

Intuice

Postupy, které podporují intuici programátorů a dlouhodobé zájmy projektu (testování, refaktorizace, integrace apod.).

Východiska řízení týmu podle XP

Komunikace

Udržení řádných komunikačních toků ovlivňuje kvalitu jednotlivých postupů XP (testování modulů, párové programování, stanovení metrik apod.).

Jednoduchost

Vývoj software je řízen zásadou, že je lepší udělat jednoduchou věc dnes, s vědomím, že zítra bude možná nutné provést další změnu, spíše než udělat složitější změnu dnes, která nemusí být uživatelem využita. Jednoduchost a komunikace jsou spolu komplementární. Čím více tým komunikuje, tím je mu jasnější co přesně má dělat. Naopak čím je jednodušší systém, tím méně potřebujeme komunikovat.

Odvaha

Členové týmu jsou ochotni experimentovat s vyšším rizikem a ziskem.

Hlavní zásady XP

Kvalitní práce

představuje fixní proměnnou ze čtyř proměnných pro posouzení projektu (šíře zadání, náklady, čas a kvalita) s hodnotou vynikající, při horší hodnotě členy týmu práce nebude bavit a projekt může skončit neúspěchem.

Vedlejší zásady XP

Hraní na výhru

představuje soustředění práce týmu na kvalitu vyvíjeného produktu, nikoli na zbytečné alibistické činnosti, kdy tým pracuje „podle předpisů“ (mnoho papírů a porad), aby se tzv. „neprohrálo“.

Konkrétní experimenty

kdy všechna abstraktní rozhodnutí by měla být převedena do řady experimentů, které jsou následně otestovány.

Práce v souladu s lidskými instinkty

a nikoli proti nim představuje práci s krátkodobými zájmy lidí, kteří se rádi učí, vyhrávají, komunikují s ostatními apod.

Cestování nalehko

představuje hodnotné a účinné nástroje vývoje softwaru, které tvoří především testy a zdrojový text.

Vývojové činnosti XP

  1. Psaní zdrojového textu

  2. Testování

  3. Poslouchání

  4. Navrhování logiky systému

Hlavní techniky XP

  • Plánovací hra stanoví šíři zadání následující verze software pomocí kombinace obchodních priorit a technických odhadů.

  • Malá verze představuje rychlé uvedení jednoduchého systému do provozu. Následně jsou uvolňovány malé přírůstky systému ve velmi krátkých cyklech.

  • Metafora pomáhá všem v projektu pochopit základní prvky systému a vztahy mezi nimi na základě jednoduchého přirovnání.

  • Jednoduchý návrh u něhož je nadbytečná složitost ihned odstraněna v okamžiku jejího zjištění z návrhu.

  • Testování představuje činnost programátorů a zákazníků, kdy programátoři testují zdrojový text z hlediska jeho programových vlastností, aby mohli pokračovat v jeho dalším psaní, a kdy uživatelé otestují funkcionalitu modulu, která je úspěšným provedením testu dokončena.

  • Refaktorizace představuje restrukturalizaci systému s cílem zdokonalení jeho nefunkčních kvalit (pružnost, zjednodušení) bez vlivu na jeho chování.

  • Párové programování představuje vývoj zdrojového textu dvěma programátory na jednom počítači.

  • Společné vlastnictví

  • Nepřetržitá integrace - okamžitá integrace dokončeného otestovaného přírůstku do systému.

  • 40 hodinový týden plus se nepracuje nikdy přesčas dva týdny za sebou.

  • Zákazník na pracovišti - odpovídá na otázky programátorů při vývoji software.

  • Standardy pro psaní zdrojového textu

Fáze XP projektu

Plánování

představuje stanovení termínu programátory společně se zákazníky na základě postupu plánovací hry. Do uvolnění první verze by mělo trvat mezi dvěma až šesti měsíci.

Smrt

představuje stav systému, kdy je software neschopen své existence z důvodu neekonomického rozšíření jeho funkcionality, entropie (tendence k většímu počtu chyb). Zákazníci i manažeři by měli souhlasit s ukončením údržby systému s tím, že se snaží identifikovat příčiny zániku systému.

KISS (Keep It Simple, Stupid)

Princip KISS

Netýká se jen programování, je to obecný princip vývoje či realizace čehokoli.

Snahou je produkovat co nejjednodušeji, bez zbytečností, bez nadbytečností, s minimem chyb.

KISS přístup patří do základního arzenálu Agilního programování.

Ideovými předchůdci principu jsou např.:

Zásada - navrhovat jednoduše

  • Realizovat věci nejjednodušším možným způsobem.

  • Tak se předejde nadměrné složitosti vytvářeného artefaktu.

  • Je větší šance, že produkt bude bez chyb.

  • Vynakládání prostředků lze při dodržení této zásady lépe kontrolovat.

Zásada - netvořit do zásoby

  • Nemá se tvořit (programovat) "dopředu", "do zásoby".

  • Ze zkušeností totiž vyplývá, že takové artefakty obvykle už nepoužijeme.

Refaktoring

Refaktoring - proč

Aplikace se vyvíjejí často překotně, pak je třeba "předělávat".

Refaktoring je právě takové "předělávání":

  • přepis beze změny (vnějšího) chování/rozhraní

  • směřuje ke zpřehlednění,

  • optimalizaci,

  • lepší rozšiřitelnosti

  • robustnosti atd.

Refaktoring - metody

Hlavní metody:

  • manipulace na úrovni návrhu: přesuny tříd mezi balíky, přejmenování tříd

  • přesuny metod mezi třídami

  • vysunutí metody do nadtřídy

  • "vytknutí" (do) rozhraní

  • zapouzření datového prvku (proměnné) přístupovými metodami

  • ...

Refaktoring - nástroje kom.

Kvalitní komerční:

  • RefactorIT - vč. free trial

Refaktoring - nástroje o-s

Základní i v open-source:

  • Eclipse 3.0

  • NetBeans 4.0

Programování řízené testy (Test-drive Development, TDD)

Motivace

  • Klasický způsobe vývoje SW předpokládá testování jako následnou fázi - testy se píší a spouštějí až po návrhu software

  • To je však paradoxní, protože návrh testů vychází - stejně jako návrh vlastního kódu - ze specifikace a to dokonce přímočařeji. Test je přímý odraz specifikace, protože programovým kódem hlídá chování, které je specifikací očekáváno.

  • Programování řízené testy proto předřazuje návrh a implementaci testů před vývoj vlastního SW.

  • Jde o metodiku vývoje samotného SW, ne testů.

Principy

  • Nejprve sestavit test, pak psát kód.

  • Stejný cíl jako Návrh dle kontraktu (Design by Contract), ale separuje testy od kódu, testuje "zvenčí".

  • Výhody: včasná (okamžitá) detekce chyb v kódu

  • Nevýhody: nelze použít tam, kde je obtížné automatizovaně testovat

Kde nelze testovat?

... resp. teoreticky lze, prakticky však chybí přijatelné nástroje a metodiky:

  • distribuovaná prostředí (částečně již lze: např. Cactus pro webové aplikace)

  • grafická uživatelská rozhraní (i tam částečně lze: pomocí "robotů" na obsluhu GUI - na simulaci klikání a ovládání klávesnice)

Generický postup TDD

  1. Napsat test - na základě specifikace (požadavků) reprezentovaných např. případy užití (usecases).

    Test bude používat samotný kód prostřednictvím rozhraní.

  2. Napsat kód - aby splnil specifikaci a komunikoval se světem pomocí rozhraní (API).

  3. Spustit automatizované testy.

  4. V případě chyb kód přeprogramovat (refactoring) a

  5. spustit testy znovu.

Systémy správy verzí

Motivace

Systémy pro správu verzí jsou nezbytností pro

  • údržbu větších SW projektů
  • projektů s více účastníky
  • projektů s vývojem z více míst

Pouhý sdílený, vzdáleně přístupný souborový systém nestačí.

Principy

  • efektivně ukládat více verzí souborů i adresářů (často s malými změnami)
  • rychle získávat aktuální verzi, ale
  • mít možnost vrátit se ke starší verzi
  • zjistit rozdíly mezi verzemi
  • zajišťovat proti souběžné editaci z více míst
  • umožnit i lokální práci s následným potvrzením do systému (commit)

Klasická řešení - RCS a CVS

RCS
Revision Control System
CVS
Concurrent Version System

RCS je klasický, původně na UNIXech existující systém navržený pro sledování více verzí souborů.

Prvotním cílem bylo zefektivnit ukládání více verzí

  • s novou verzí se nemusí ukládát celý soubor
  • rychle se dají zjistit rozdíly (změny) mezi verzemi
  • historie změn (changelog, history) se lehce udržuje
  • změny lze identifikovat i názvy - pojmenovat symbolickými klíčovými slovy ($Author$, $Date$...)

Typické příkazy správy verzí

(podobné jsou v CVS, SVN)

commit
publikuje (odešle, potvrdí) změny z lokálního pracovního prostoru do skladu (repository)
remove
maže soubory z lokálního pracovního adresáře, ze skladu se smažou až po "commit"
add
přidá nový soubor do pracovního adresáře, do skladu se přidají až po "commit"
update
aktualizuje lokální kopii pomocí změn zaregistrovaných ostatními ve skladu
ckeckout
vytvoří soukromou lokální kopii požadovaných souborů ze skladu, tyto můžeme lokálně editovat a posléze potvrdit (commit) zpět

Klienti

Syst. správy verzí nabízejí

  • nativní klienty integrované do hostujícího prostředí
  • webové rozhraní spíše pro prohlížení
  • API pro přímý/programový přístup

Pro co se systémy nehodí?

  • pro ukládání (stabilních) artefaktů
  • jako úložiště (read-only) souborů pro stahování
  • ... kdyby se to hodilo na všechno, nabízel by to každý filesystém...

Subversion

  • implementace systému řízení verzí
  • moderní alternativa CVS
  • jako server dostupný na všechny běžné platf. (zejm. Linux, Win)
  • server existuje jako samostatná aplikace, standardní použití je však s webových serverem Apache

  • klienti taktéž, např. na Win

Subversion - klient Tortoise pro Windows

Klient pro Win 2k, XP i 98... vč. integrace do GUI

  • kontextové nabídky
  • nativní nástroje

Tortoise -- vzdálený přístup

  • Tortoise umožňuje bezpečný přístup k vzdálenému úložišti i prostřednictvím šifrovaných protokolů
  • (server potom ale musí běžet přes Apache...)

  • používá se upravený klient PuTTY

Správa sestavování - Ant

Charakteristika

  • Ant je platformově přenositelnou alternativou nástroje typu Make
  • Ant je rozšiřitelný - lze psát nejen nové "cíle", ale i definovat dílčí kroky - "úlohy"
  • Popisovače sestavení používají XML syntaxi, psaní není tak náročné jako makefile

Motivace

  • Proč Ant, když je tu dlouho a dobře fungující Make?
  • Make byl koncipován jako doplněk shellu, psaly se skripty a nativní (platformové) nástroje
  • Syntaxe byla složitá a neflexibilní
  • Make jako takový nebyl rozšiřitelný
  • Make byl zaměřen převážně na potřeby původního použití - jazyk C, unixový shell

Struktura projektu

Řízení sestavování Antem postupuje podle popisu v souboru build.xml.

Ten obsahuje následující prvky:

project
celý projekt, obsahuje sadu cílů, jeden z nich je hlavní/implicitní
target
cíl, nejmenší zvenčí spustitelná jednotka algoritmu sestavování
task
úloha, atomický krok sestavení, lze použít task vestavěný nebo uživatelský

Příklad 1

Závislosti

  • Mezi cíly mohou být definovány závislosti.
  • Závisí-li volaný cíl na jiném, musí být nejprve splněn cíl výchozí a pak teprve cíl závisející.
  • Cíl může záviset i na více jiných.
<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
[Varování]Varování

Pozor na cyklické závislosti!

Příklad 2

Maven

Motivace

Pro sestavování, správu a údržbu SW projektů menšího a středního rozsahu se delší dobu úspěšně využíval systém Ant.

Oproti klasickým nástrojům typu unixového make poskytoval Ant platformově nezávislou možnost popsat i složité postupy sestavení, testování a nasazení výsledků SW projektu.

Ant měl však i nevýhody:

  • pro každý projekt (i když už jsme podobný řešili) musíme znovu sestavit - poměrně velmi technický - popisovač (build.xml)

  • popisovač je vždy téměř stejný a tudíž

  • neříká nic o obsahu vlastního projektu, je jen o procesu sestavení, nasazení...

  • neumožňoval zachytit metadata nezbytná pro zařazení projektu do širšího kontextu, mezi související projekty, atd.

Maven - charakteristika

  • nástroj řízení SW projektů

  • open-source, součást skupiny nástrojů kolem Apache

  • dostupný a popsaný na http://maven.apache.org

  • momentálně (září 2004) již jako použitelná, ostrá, verze 1.0

Project Object Model (POM)

  • projekt řízený Mavenem je popsán tzv. POM (Project Object Model), obvykle project.xml

  • POM nepopisuje postup sestavení, ale obsah projektu, jeho název, autora, umístění, licenci...

  • postup sestavení je "zadrátován" v Mavenu, protože je pro většinu projektů stejný

  • programátor není frustrován opakováním psaní popisovačů build.xml, návrhem adresářové struktury...

  • nicméně, Maven je založen na Ant, jeho build.xml popisovače lze znovupoužít

Projekt v Mavenu

Základní filozofie projektu v Mavenu:

  • jeden projekt => jeden tzv. artefakt

Artefaktem může být typicky:

  • .jar - obyčejná aplikace nebo knihovna (javové třídy, soubory .properties, obrázky...)

  • .war - webová aplikace (servlety, JSP, HTML, další zdroje, popisovače)

  • .ear - enterprise (EJB) aplikace (vše výše uvedené pro EJB, popisovače)

Maven repository

  • základním organizačním nástrojem pro správu vytvořených (nebo používaných) artefaktů je repository

  • artefakt, tj. výstup projektu, se může v repository vyskytovat ve více verzích

  • repository je:

    vzdálená (remote)

    slouží k centralizovanému umisťování jak vytvořených, tak používaných artefaktů

    dosažitelná pro čtení pomocí HTTP: je to de-facto běžné webové místo

    lokální (local)

    slouží k ozrcadlení používaných artefaktů ze vzdálené repository

    typicky zvlášt každému uživateli - v jeho domovském adresáři

    slouží též k vystavení vytvořených artefaktů "pro vlastní potřebu"

  • Maven má nástroje (pluginy) pro vystavování artefaktů do repository

Instalace a nastavení

Maven lze stáhnout z http://maven.apache.org v binární i zdrojové distribuci.

Binární distribuce je buďto čistě "java-based" nebo ve formě windowsového .exe.

Pak se nainstaluje do Program Files

Po instalace je třeba nastavit proměnnou prostředí MAVEN_HOME na adresář, kam se nainstaloval.

Kromě toho ještě přidat adresář %MAVEN_HOME%\bin do PATH.

Příklad POM (project.xml)

Příklad minimálního popisovače project.xml:

<project>
   <pomVersion>3</pomVersion><!-- verze POM - zatím vždy 3 -->
   <id>RunningCalculator</id><!-- jednoznačné id projektu -->
   <name>RunningCalculator</name><!-- (krátké) jméno/nemusí být jednoznačné -->
   <currentVersion>0.1</currentVersion><!-- momentální verze -->
   <organization><!-- organizace vytvářející projekt -->
      <name>Object Computing, Inc.</name>
   </organization>
   <inceptionYear>2004</inceptionYear><!-- rok zahájení projektu -->
   <shortDescription>calculates running pace</shortDescription><!-- stručný popis -->
   <developers/>

Příklad POM - pokračování

Příklad minimálního popisovače project.xml:

   <dependencies><!-- závislosti -->
      <dependency><!-- závislost -->
         <groupId>junit</groupId><!-- skupina artefaktu -->
         <artifactId>junit</artifactId><!-- označení artefaktu -->
         <version>3.8.1</version><!-- verze artefaktu -->
      </dependency>
   </dependencies>
   <build><!-- odkud se co a jak sestavuje... -->
      <sourceDirectory>src/java</sourceDirectory><!-- adresář zdrojů -->
      <unitTestSourceDirectory>src/test</unitTestSourceDirectory><!-- adresář zdrojů testů -->
      <unitTest><!-- které soubory jsou třídy testů -->
         <includes>
            <include>**/*Test.java</include>
         </includes>
      </unitTest>
   </build>
</project>

Struktura POM obecně

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="MAVEN_HOME/maven-project.xsd">
   <pomVersion>3</pomVersion>
   <id>unique-project-id</id>
   <name>project-name</name>
   <groupId>repository-directory-name</groupId>
   <currentVersion>version</currentVersion>
   <!-- Management Section -->
   <!-- Dependency Section -->
   <!-- Build Section -->
   <!-- Reports Section -->
</project>

Proměnné (properties) v POM

  • Jsou podobně jako u Antu definovatelné a využitelné (odkazovatelné) v popisovači, zde project.xml.

  • Vyskytne-li se zavedení určité vlastnosti (property) vícekrát, uplatní se poslední.

  • Vlastnosti jsou vyhledávány v pořadí:

    1. project.properties

    2. build.properties

    3. ${user.home}/build.properties

    4. vlastnosti specifikované na příkazové řádce -Dkey=value

  • Na vlastnost se lze odvolat pomocí ${property-name}

Struktura repository

Týká se jak vzdálené, tak lokální repository.

Obecně je relativní cesta v rámci repository k hledanému artefaktu: repository/resource-directory/jars/jar-file

konkrétní např.: repository/junit/jars/junit-3.8.1.jar

Cíle v Mavenu

Cíle (goals) v Mavenu odpovídají zhruba antovým cílům (target).

Spouštění Mavenu vlastně odpovídá příkazu k dosažení cíle ("attaining the goal"):

maven plugin-name[:goal-name]

Maven Plugins

Zásuvné moduly (plugins) obsahují předdefinované cíle (goals) a jsou taktéž uloženy v repository.

Většinou jsou jednoúčelové, slouží/směřují k jednomu typu artefaktu, např.:

  • checkstyle, clean, clover, cruisecontrol, dist, ear, eclipse, ejb, fo, genapp, jalopy, jar, java, javadoc, jboss, jcoverage, maven-junit-report-plugin, pom, site, test, war, xdoc

Často používané cíle

clean

smaže vygenerované soubory (podstrom target)

java:compile

přeloží všechny javové zdroje

test

spustí všechny testy

site

vygeneruje webové sídlo projektu

dist

vygeneruje kompletní distribuci

Vytvoření projektu

  1. vytvořit prázdný adresář pro vytvářený projekt

  2. spustit maven genapp (Zeptá se na id projektu, jeho jméno a hlavní balík. V něm předgeneruje jednu třídu.)

  3. tím se vytvoří následující soubory:

    • project.xml, project.properties

    • src/conf/app.properties

    • src/java/package-dirs/App.java

    • src/test/package-dirs/AbstractTestCase.java

    • src/test/package-dirs/AppTest.java

    • src/test/package-dirs/NaughtyTest.java

Reporting

Generování reportů (zpráv) je jednou se základních funkcí Mavenu.

Které reporty se generují, je regulováno v project.xml v sekci reports:

<reports>
   <report>maven-checkstyle-plugin</report>
   <report>maven-javadoc-plugin</report>
   <report>maven-junit-report-plugin</report>
</reports>

Rozšíření možností Mavenu

Cílů (goals) je sice v Mavenu řada, ale přesto nemusejí stačit anebo je třeba měnit jejich implicitní chování.

Potom lze před nebo po určitý cíl připojit další cíl pomocí preGoal a postGoal.

Ty se specifikují buďto v nebo.

  1. maven.xml ve stejném adresáři jako project.xml nebo

  2. v zásuvném modulu (pluginu)

Zcela nové cíle je možné napsat ve skriptovacím jazyku jelly (s XML syntaxí).

Kapitola 3. Webové aplikace.

Webové aplikace

Jan Pavlovič

Tomáš Pitner

Aug 2005


Seznam obrázků

31..1. Použití servletu
31..2. Životní cyklus servletu

Seznam příkladů

31..1. HelloClientServlet.java
32..1. web.xml
32..2. build.properties

Kapitola 1. Úvod - Servlety a JSP

Technologie JSP a Java Servlety jsou jedny ze základních technologií Java™ 2 Platform, Enterprise Edition (J2EE).

Servlet je program v Javě, který rozšiřuje funkcionalitu webového serveru, generuje dynamický obsah a komunikuje s webovými klienty pomocí request-response paradigmatu.

JavaServer Pages™ (JSP) je abstrakce servletového modelu. JSP stránky jsou rozšiřující webovou technologií, využívající značkovací šablony, specifikovatelné elementy, skriptovací jazyky a server-side Java objekty pro zpřístupnění dynamického obsahu klientovi. Nejčastěji se jako šablony používají HTML či XML elementy a ve většině případů je klientem webový browser.

Specifikace servletu a JSP je dostupná na: http://java.sun.com/products/servlet a http://java.sun.com/products/jsp.

Servlety

Servlety jsou reakcí Javy na CGI scripty. Jedná se o programy v Javě, které běží na webovém serveru a odpovídají na požadavky ze stany klientů. Servlety nejsou spjaty s žádným konkrétním client-server protokolem, nicméně nejširší využití servletů je s HTTP protokolem. Označením „Servlet“ je tedy často míněn „HTTP Servlet“.

Servlety jsou implementací tříd v balíku javax.servlet (základní Servlet framework) a javax.servlet.http (rozšíření Servlet frameworku pro servlety odpovídají na HTTP požadavky). Jelikož jsou servlety napsáný ve vysoce portabilním jazyku a s splňují požadavky na framework, umožňují vytváření sofistikovaných serverových aplikací nezávisle na operačním systému.

Servlety se používají zejména pro:

  • Zpracování a ukládaní dat z HTML formulářů.
  • Generovaní dynamického obsahu např. vracení databázových dotazů klientovi.
  • Manipulace se stavovými informacemi nad bezstavovým HTTP protokolem např. realizace on-line nákupního sytému, který souběžně obsluhuje několik zákazníků a přiřazuje každý požadavek odpovídajícímu zákazníkovi.

Servlety vs CGI

Tradiční způsob přidávání další funkcionality webovému serveru je pomocí Common Gateway Interface (CGI), jedná se o jazykově nezávislý interface, který umožňuje serveru spouštět externí procesy. Každý požadavek je zodpovězen separátní instancí CGI scriptu.

Servlety mají nad CGI několik výhod:

  • Servlet neběží v separátním procesu. Což odstraňuje zátěž s vytvářením nového procesu pro každý požadavek.

  • Servlet zůstává v paměti mezi požadavky. CGI script je nutné nahrávat a spouštět pro každý požadavek.

  • Existuje pouze jediná instance servletu, která souběžně obsluhuje všechny požadavky. Tímto se ušetří paměť a zároveň může servlet jednoduše obsluhovat všechna data.

  • Servlet může běžet v sandboxu a mít tak pevně definované bezpečnostní omezení.

Použití servletu

Na obrázku 1 je zobrazen jeden z nejčastějších využití servletů. Uživatel (1) vyplní formulář, který se odkazuje na servlet a kliknutím na submit tlačítko vyšle požadavek na informaci (2). Server (3) lokalizuje požadovaný servlet (4). A teď vyhodnotí a vrátí požadované informace ve formě web stránky (5). Ta je poté zobrazena v uživatelově prohlížeči (6).

Obrázek 31..1. Použití servletu

Použití servletu

Základní struktura servletů

Servlet ve své nejobecnější formě je instance třídy, která implementuje javax.servlet.Servlet interface. Většina servletů je potomkem jednoho ze standardních implementací tohoto interfacu, jmenovitě javax.servlet.GenericServlet a javax.servlet.http.HttpServlet.

Při inicializaci servletu načte server třídu servletu (a ostatní odkazované třídy) a vytvoří instanci voláním bezparametrového konstruktoru. Následně zavolá metodu servletu init(ServletConfig config). Servlet při vykonávání této metody uloží ServletConfig objekt, který bude dostupný metodou getServletConfig(). Toto vše je obstaráno GenericServletem. Servlety, které jsou potomky GenericServletu (nebo jeho podtřídy HttpServlet) by měli volat super.init(config) na začátku metody init. Vzniklý objekt ServletConfig obsahuje parametry servletu a odkaz na ServletContext obsahující runtime environment informace. Metoda init je v životním cyklu servletu volána pouze jednou.

Poté co je servlet inicializován, je jeho metoda service(ServletRequest req, ServletResponse res) volána pro každý požadavek na servlet. Tato metoda je volána souběžně (např. multiple threads mohou volat tuto metodu ve stejný okamžik) a tudíž je nutné, aby byla implementována jako thread-safe.

V případě potřeby odstranění servletu z paměti (např. z důvodu nahrání nové verze nebo vypínaní serveru) je volána metoda destroy().

Obrázek 31..2. Životní cyklus servletu

Životní cyklus servletu

HTTP

Ještě před tím, než se pustíme do psaní našeho prvního servletu, musíme znát několik základních rysů HTTP protokolu.

HTTP je request-response orientovaný protokol. HTTP požadavek se skládá z metody request , URI, hlaviček a těla dotazu. HTTP odpověď obsahuje kód odpovědi, hlavičky a tělo.

Metoda service HttpServletu rozděluje požadavek vstupním metodám servletu podle typu HTTP požadavku. Jsou rozeznávaný standardní HTTP/1.1 metody: GET, HEAD, PUT, POST, DELETE, OPTIONS a TRACE. Ostatní metody jsou vráceny jako: Bad Request HTTP error. HTTP metoda XXX je přiřazena metoda servletu doXxx, (GET -> doGet()). Všechny tyto metody očekávají parametry „(HttpServletRequest req, HttpServletResponse res)“. Metody doOptions() a doTrace() mají dostatečnou defaultní implementaci a obvykle je nepředefinovávají. Metoda HEAD (která vrací pouze hlavičky) je řešena voláním doGet() a ignorací výstupu této metody. Tím nám zůstávají metody doGet, doPut, doPost a doDelete, jejich výchozí implementace v HttpServletu vrací: Bad Request HTTP error. Podtřída HttpServletu předefinovává jednu či více těchto metod smysluplnou implementací.

Data požadavku vstupují do servletu přes první argument typu HttpServletRequest (který je podtřídou obecnější třídy ServletRequest). Odpověď může být vytvořena skrz druhou proměnou, která je typu HttpServletResponse (podtřída ServletResponse).

V okamžiku, kdy v našem prohlížeči zadáme požadavek na URL, je použita metoda GET. Odpověď se bude skládat z těla odpovědi a hlaviček popisující tělo (obzvláště Content-Type a Content-Encoding). Pokud posíláme HTML formulář, můžeme použít metodu GET nebo POST. S GET požadavkem jsou parametry zakódovaný v URL a s POST požadavkem jsou přeneseny v těle požadavku.

Náš první servlet

Začneme obvyklým „Hello World“ příkladem

Příklad 31..1. HelloClientServlet.java

 1:  import java.io.*;
 2:  import javax.servlet.*;
 3:  import javax.servlet.http.*;
 4:
 5:  public class HelloClientServlet extends HttpServlet
 6:  {
 7:    protected void doGet(HttpServletRequest req,
 8:                         HttpServletResponse res)
 9:              throws ServletException, IOException
10:    {
11:      res.setContentType("text/html");
12:      PrintWriter out = res.getWriter();
13:      out.println("<HTML><HEAD><TITLE>Hello Client!</TITLE>"+
14:                  "</HEAD><BODY>Hello Client!</BODY></HTML>");
15:      out.close();
16:    }
17:  }

Podívejme se jak daný servlet funguje.

Řádky 1 až 3 importují balíky potřebné pro běh servletu.

 1:  import java.io.*;
 2:  import javax.servlet.*;
 3:  import javax.servlet.http.*;

Třída servletu je deklarovaná na řádku 5. Servlet dědí třídu javax.servlet.http.HttpServlet, standardní třída pro HTTP servlety.

 5:  public class HelloClientServlet extends HttpServlet

Na řádcích 7 až 16 je předefinovaná metoda doGet() HttpServletu.

 7:    protected void doGet(HttpServletRequest req,
 8:                         HttpServletResponse res)
 9:              throws ServletException, IOException
10:    {
         ...
16:    }

Na řádku 11 je pro nastavení content type odpovědi použita metoda třídy HttpServletResponse. Všechny hlavičky odpovědi musí být nastaveny před tím než je zavolán PrintWriter nebo ServletOutputStream pro výpis dat.

11:      res.setContentType("text/html");

Řádek 12: pomocí třídy PrintWriter je zapsán text do odpovědi.

12:      PrintWriter out = res.getWriter();

13 až 14 no comment ...

13:      out.println("<HTML><HEAD><TITLE>Hello Client!</TITLE>"+
14:                  "</HEAD><BODY>Hello Client!</BODY></HTML>");

Po ukončení zápisu zavíráme na řádku 15 PrintWriter.

15:      out.close();

Tento řádek je uveden pro úplnost. Není striktně vyžadován. Web server zavírá PrintWriter nebo ServletOutputStream automaticky po návratu metody service.

JSP

TODO

Kapitola 2. Servlet/JSP containers

Servlet/JSP container umožňuje používání JSP souborů. Container dostane (od webového serveru) JSP soubor, ke zpracování, přeloží ho do java-byte kódu, provede a výstup předá zpátky (webovému serveru).

Tomcat

Jedním z nejpoužívanějších Servlet/JSP containerů je Apache Jakarta Tomcat. http://jakarta.apache.org/tomcat

Tomcat verze 5.5 implementuje Servlet 2.4 a JavaServer Pages 2.0 specifikaci a obsahuje mnoho dalších vlastností, které z něj činní vhodnou platformu pro vývoj a provoz webových aplikací a webových služeb.

Adresářová struktura Tomcatu

  • bin - startovací scripty

  • common - adresář pro třídy a balíky sdílené všemi aplikacemi i serverem

  • conf - soubory s konfigurací serveru

  • logs - výstup a logy serveru

  • server - knihovny nezbytné pro běh serveru

  • shared - adresář pro třídy a balíky sdílené všemi aplikacemi

  • webapps - úložiště pro aplikace

  • work - pracovní adresář pro běžící aplikace

  • temp - adresář používaný JVM pro dočasné soubory (java.io.tmpdir)

Obsluha serveru

Tomcat se spouští pomocí příkazu startup.sh, poté je server dostupný na portu 8080 na daném serveru http://localhost:8080

Ukončení běhu serveru se provádí příkazem shutdown.sh

Struktura aplikace

Top-level adresář ve struktuře aplikací je i kořenovým adresářem naší aplikace. Po nahrání aplikace na server bude dostupná právě pod jménem aplikace: např soubor index.html v aplikaci catalog, bude odkazovaná jako http://server/catalog/index.html

Vnitřní struktura aplikace odpovídá formátu WAR souboru

  • *.html, *.jsp, atd. - HTML a JSP stránky musí být spolu s ostatními soubory viditelné pro prohlížeče klientů (to platí i pro JavaScript, CSS a obrázky). V rozsáhlejších aplikacích se přistupuje do rozdělení těchto souborů do jednotlivých podadresářů

  • /WEB-INF/web.xml - (Web Application Deployment Descriptor) je XML soubor pro naši aplikaci popisující servlety a ostatní komponenty v aplikaci. Dále obsahuje případné definice inicializačních parametrů a bezpečnostních omezen.

  • /META-INF/context.xml (Tomcat Context Descriptor) je soubor, který může být použit pro specifické definice Tomcatu jako: loggers, data sources, session manager configuration a další.

  • /WEB-INF/classes/ - Adresář obsahující zkompilované soubory servletů a ostatních tříd, které nejsou zabalené v JAR archívu. Pokud máme třídy organizované v balíčcích, musíme respektovat tuto adresářovou strukturu i v /WEB-INF/classes/ např. třída com.mycompany.mypackage.MyServlet musí být uložena v souboru /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class.

  • /WEB-INF/lib/ - Adresář obsahující JAR soubory.

Struktura zdrojových kódů aplikace

Základní myšlenka strukturu naší aplikace je oddělení zdrojových kódu od binárních. Takovéto rozděleni přináší následující výhody:

  • Obsah zdrojových adresářů lze jednoduše spravovat, přesouvat a zálohovat.

  • Správa zdrojových kódů je jednodušší pokud adresáře obsahují pouze zdrojové soubory.

  • Distribuční soubory jsou hierarchicky oddělené od zdrojových.

Později uvidíme, že vytváření hierarchické struktury adresářů za pomocí antu je velmi snadné.

Doporučená struktura adresářů:

  • docs/ - Dokumentace.

  • src/ - Java zdrojové kódy pro servlety, beany a další třídy. Pokud jsou zdrojové soubory organizovány do balíčků (což je vřele doporučováno), musí struktura balíčku odpovídat struktuře adresářů.

  • web/ - statické stránky (HTML, JSP, JavaScript, CSS a obrázky). Tento adresář bude kořenovým adresářem webové aplikace. Veškerá podadresářová struktura bude zachována.

  • web/WEB-INF/ - konfigurační soubory pro aplikaci (web.xml), taglibs a jiné. Soubory v tomto adresáři nebudou přístupné klientům. Z tohoto důvodu je právě toto místo vhodné pro ukládaní konfiguračních souboru s citlivými informacemi (hesla k přístupu do databáze).

V průběhu kompilace dojde k vytvoření dvou adresářů:

  • build/ - po spuštění antu obsahuje tento adresář kompletní obraz přeložené aplikace.

  • dist/ - do toho adresáře umístí ant war soubor s aplikací

Není vhodné do aplikace začleňovat JAR soubory běžných aplikací. Ty je vhodnější umístit na server do sdílených složek common nebo shared.

Taktéž není příliš vhodné umisťovat přiložené třídy do SVN repozitory.

web.xml

V souboru web.xml je uveden popis aplikace, použití různých filtrů, taglibs, servletů atd. V následují ukázce je uvedeno na jaký odkaz má Tomcat přemapovat servlet HelloWorldExampleServlet, který je spouštěn třídou mypackage.HelloWorldExample.

Příklad 32..1. web.xml

<!DOCTYPE web-app 
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>Hello, World Application</display-name>
  <description>
    This is a simple web application with a source code organization
    based on the recommendations of the Application Developer's Guide.
  </description>

  <servlet>
    <servlet-name>HelloWorldExampleServlet</servlet-name>
    <servlet-class>mypackage.HelloWorldExample</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>HelloWorldExampleServlet</servlet-name>
    <url-pattern>/HelloWorldExample</url-pattern>
  </servlet-mapping>
</web-app>

Instalace aplikace

Existují dva hlavní způsoby jak svou aplikaci do Tomcatu nainstalovat:

  • Použít webovou nástavbu tomcat manageru, což je nástroj který umožňuje instalovat do Tomcatu aplikace. Buď můžeme použít jeho grafickou nástavbu: a aplikaci zabalenou do war jím nainstalovat http://kore.fi.muni.cz:8080 a nebo, což je úplně nejjednodušší, použít Ant, který za nás aplikaci do waru sestaví a managerem nainstaluje. K tomu abychom mohli manažer používat, je nutné buď znát heslo managera nebo jako uživatel mít roli managera. Jelikož uživatel v roli managera může odstraňovat veškeré aplikace, dávejte si pozor, aby jste neodstranili aplikaci i někomu jinému!

  • Použít antový target, který používá třídy z balíku catalina-ant.jar. Balík obsahuje i další targety, které umožňují plně využít veškeré schopnosti tomcat managera.

Ant

Použití Antu je snadná věc, kterou zvládne opravdu každý a ušetří si tak spoustu práce. Pro instalaci do tomcat manageru je potřeba nakopírovat soubor catalina-ant.jar z tomcatu do $ANT_HOME/lib. Ant v modulech již uvedený soubor obsahuje a tak není potřeba nic kopírovat. Stačí přidat Ant:

module add ant

Ant používá jako konfigurační Makefile soubor buil.xml v kterém jsou uvedeny jednotlivé targets a parametry. Pro základní použití není potřeba konfiguračnímu souboru příliš rozumět, navíc je možné parametry includovat z externího souboru většinou nazvaném buil.properties, takže když potřebujeme něco změnit v konfiguraci stačí změnit několik údajů v tomto souboru a do buil.xml vůbec nezasahovat.

Příklad 32..2. build.properties

app.name=pokus12
catalina.home=/packages/share/tomcat
manager.url=http://kore.fi.muni.cz:8080/manager
manager.username=manager
manager.password=manager

Nyní již stačí aplikaci zkompilovat a nainstalovat.

ant compile

aplikaci pouze zkompiluje a výsledný war soubor uloží do adresáře /dist

ant install

aplikaci zkompiluje a nainstaluje do adresáře /webapps/${app.name}, která bude dostupná jako http://kore.fi.muni.cz:8080/${app.name}.

ant deploy

přenese war soubor aplikace do tomcatu a nainstaluje do adresáře /webapps/${app.name}, aplikace bude dostupná jako http://kore.fi.muni.cz:8080/${app.name}. T[Aento cíl umožňuje také použití vlastní konfigurací kontextu aplikace, které uvedeme v souboru context.xml. Aplikace bude jednak v tomcatu nainstalována a navíc bude do tomcatu přenesen i distribuční war soubor.

ant undeploy

odstraní deploynutou aplikaci i war soubor.

ant stop

aplikaci pozastaví (nebude dostupná z webu).

ant start

aplikaci spustí pozastavenou aplikaci.

ant reload

zastaví aplikaci a provede její znovu načtení.

[Poznámka]Poznámka

konfigurace aplikace uložená v souboru /WEB-INF/web.xml není při reloadu znovu načtena a je použita konfigurace předchozí. Pokud jsme udělali změny konfiguračním souboru je nutné aplikaci nejprve zastavit a opětovně spustit.

Ukázková aplikace

Nejlepší je se inspirovat již nějakou hotovou aplikací: http://www.fi.muni.cz/~xpavlov/tomcat/app1.tar.gz. K dispozici je i originální ukázková aplikace z distribuce tomcatu http://jakarta.apache.org/tomcat-5.0/tomcat-docs/appdev.

mod_jk2

V případě, že se do apache zkompiluje mod_jk2, není nutné pro použití JSP souboru specifikovat port, na kterém tomcat běží. Apache pak sám pozná, který soubor má předat tomcatu ke zpracování a který soubor má zpracovat sám.

Kapitola 3. Datová vrstva javových aplikací - zajištění perzistence a správy dat. JBDC, JDO, Hibernate.

Java Database Connectivity (JDBC)

Co je JDBC

  • JDBC je univerzální rozhraní pro přístup k (převážně relačním) databázím.
  • Umožňuje dotazovat se pomocí SQL i modifikovat pomocí SQL data.
  • JDBC odpovídá specifikaci X/Open SQL CLI.
  • Je k dispozici na J2SE a J2EE v balících java.sql, javax.sql.
  • Současná verze, JDBC 3.0, plně reflektuje finální verzi SQL99.

Postup práce s JDBC

Postup práce s JDBC je následující:

  1. Výrobce příslušného systému řízení báze dat (DBMS) poskytne implementaci JDBC
  2. Programátor používá JDBC k přístupu k datům spravovaným určitým DBMS - do značné míry nezávisle na konkrétním DBMS, provádí SQL příkazy...
  3. Přesná podoba (odchylky) nicméně závisí na konkrétním DBMS.

Koncepce je podobná jako ODBC (Microsoft Windows).

Hlavní třídy (komponenty) JDBC

DriverManager
manažer databázových ovladačů - každý systém řízení báze dat (DBMS) musí mít vlastní databázový ovladač (Driver). V manažeru se ovladače zaregistrují a přístup k danému DBMS se realizuje prostřednictvím příslušného ovladače.
DataSource
abstraktní "obálka" konkrétního datového zdroje. Uživatele nezajímá, kterým DBMS je zdroj řízen, stačí, že nějakou službou získá objekt DataSource a z něj vytváří spojení (Connection).
ConnectionPoolDataSource
dtto, ale _oolable_ tj. datový zdroj schopný poolingu připojení - zvýšená efektivita, není třeba vždy fyzicky zřizovat nové spojení, ale "vypůjčit si" právě nepoužívané, "volné" spojení z poolu.

Hlavní třídy (komponenty) JDBC (2)

Connection
spojení k datovému zdroji. Nad spojením se spouštějí SQL příkazy (dotazy), spojení může být předmětem transakcí.
Statement
obálka jednoho SQL příkazu.
ResultSet
obálka výsledku SQL příkazu. U dotazů (čtecích) obsahuje typicky 1 až __řádků s nedefinovaným pořadím - odtud označení ResultSet.
DatabaseMetaData
zachycuje metadata (schéma) dané databáze

Příklad - zavedení ovladače DBMS

import java.sql.*;
public class TestJDBCMySQL { 
   public static void main(String[] args) { 
      String url = "jdbc:mysql://idealab.cs.uiowa.edu/WorksOn";
      String uid = "user";
      String pw = "testpw";
      try { // Load driver class
         Class.forName("com.mysql.jdbc.Driver");
      } catch (java.lang.ClassNotFoundException e) {
         System.err.println("ClassNotFoundException: " +e);
      }
      ...

Příklad - vytvoření spojení, příkazu a jeho spuštění

   ...
   Connection con = null;
   try {
      con = DriverManager.getConnection(url, uid, pw);
      Statement stmt = con.createStatement();
      ResultSet rst = stmt.executeQuery("SELECT ename,salary FROM Emp");
      System.out.println("Employee Name,Salary");
      while (rst.next()) { 
         System.out.println(rst.getString("ename")+","+rst.getDouble("salary"));
      }
      con.close();
   } catch (SQLException ex) {
      System.err.println("SQLException: " + ex); }
   }
}

Charakteristika JDBC rozhraní

JDBC je velmi obecné rozhraní pro přístup k relačním databázím. Proto:

  • je "slabě typované", nemá např. speciální metody pro jednotlivé typy SQL dotazů, vše se spouští executeQuery.

  • totéž platí pro přístup k výsledkům dotazů: ResultSet je jednoduchý iterátor (přesněji kurzor), kde lze z aktuální pozice číst a případně na ní modifikovat.

  • vše podstatné je ponecháno na uživateli - formulaci SQL dotazů uvnitř execute, executeQuery apod. - rozhraní nezkontroluje ani syntaktickou správnost, to až samotný DB stroj.

  • taktéž výjimky jsou téměř vždy pouze SQLException s textovým popisem uvnitř

JDBC rozhraní - balíky

JDBC je rozloženo do balíků:

java.sql

základní rozhraní a třídy

javax.sql

rozšiřující rozhraní a třídy

třídy a rozhraní konkrétního DBMS

závisejí na použitém DBMS, např. balík org.hsqldb

Práce s databází

Klasickým způsobem práce s JDBC je tento postup:

  • získáme spojení typicky oslovením DriverManageru s uvedením url zdroje, jména a hesla uživatele:

    con = DriverManager.getConnection(url, uid, pw);

  • na získaném spojení vytváříme příkazy (Statement):

    Statement stmt = con.createStatement();

  • na příkazu spustíme SQL dotaz:

    ResultSet rst = stmt.executeQuery("SELECT ename,salary FROM Emp");

  • výsledky dotazu projdeme iterací výsledného ResultSetu:

    while (rst.next()) { 
             System.out.println(rst.getString("ename")+","+rst.getDouble("salary"));
    }
    
  • spojení "po použití" uzavřeme.

[Varování]Varování

Nesmíme uzavřít, dokud nedočteme ResultSet - jeho zbytek by se ztratil.

[Poznámka]Poznámka

Také se obecně nelze v ResultSetu vracet.

[Poznámka]Poznámka

Je nutné počítat s tím, že ResultSet neexistuje v jednu chvíli v paměti celý; je to virtuální přístupový bod k výsledkům, které se obecně postupně načítají/generují.

Transakce

Implicitně se pro zřízené spojení nastaví režim "auto-commit", každý dotaz je uzavřen do samostatné transakce.

Chceme-li toto změnit (což je vzhledem k výkonu i vhodné), nastavíme con.setAutoCommit(false) a řídíme si transakce sami.

Řízení transakcí provádíme na daném spojení pomocí:

commit()

potvrdí a trvale uloží změny provedené od posledního commit/rollback

rollback()

"zahodí" změny provedené od posledního commit/rollback, tj. vrátí databázi do stavu po posledním commit/rollback

rollback(Savepoint p)

vrátí databázi do stavu p

Transakce - příklad

Příklad kódu s řízením transakce: první změna je potvrzena (commit), druhá zamítnuta (rollback):

con.setAutoCommit(false);

// inserts first two messages
for (int i = 0; i < messages.length-1; i++) {
   stmt.executeUpdate(
          "INSERT INTO MESSAGES VALUES (" ... ")");
      
con.commit();

// inserts last message ?
stmt.executeUpdate(
          "INSERT INTO MESSAGES VALUES (" ... ")");
// no. last message will not be inserted!
con.rollback();  

Demo - HSQLDB

Na rychlé a nenáročné vyzkoušení databázových věcí v Javě můžeme použít volně dostupný javový systém řízení báze dat HSQLDB (dříve HypersonicSQL), http://hsqldb.sf.net.

Všechny demoprogramy dostupné ve zdrojové podobě jsou bez úprav učené pro HSQLDB.

HSQLDB - režimy práce

HSQLDB může pracovat ve třech režimech:

in-memory/in-proces

běží v rámci procesu klientského programu, není nutné spouštět zvlášť, pouze v programu přistoupíme k databázi pomocí zvláštního URL - viz manuál HSQLDB nebo příklady

standalone

DB server běží zvlášť, tudíž je přístupný více klienty, tabulky se ukládají na disk

webserver

dtto, přístupné přes HTTP přes mini HTTP-server

Předpřipravené příkazy

Předpřipravené příkazy (Prepared Statements) jsou prostředkem, jak efektivně provádět často opakované SQL dotazy, např.:

  • více vložení do stejné tabulky

  • dotazy, kde mění jen jeden parametr, např. hledaný klíč

Technicky předpřipravený dotaz vypadá tak, že na místě dosazovaného parametru je znak ?.

Pomocí set-metod se daný formální parametr ("otazník") nahradí skutečnou hodnotou a pak se příkaz spustí.

Předpřipravené příkazy - příklad

Příklad:

// příprava příkazu
PreparedStatement pstmt = con.prepareStatement(
        "SELECT E.FIRSTNAME, E.SURNAME, M.CREATED, M.TEXT " +
        "FROM EMPLOYEES AS E, MESSAGES AS M " +
        "WHERE E.SURNAME = ?"
        +" AND E.ID = M.TO " +
        "ORDER BY M.CREATED DESC");

// naplnění parametrů
pstmt.setString(1, "Novak");

// vlastní provedení
ResultSet result = pstmt.executeQuery();

Uložené procedury

Uložené procedury - Stored Procedures - jsou vzdáleně podobné předpřípraveným příkazům, jsou však zcela v server-side režii.

Běží tedy vzdáleně přímo na serveru.

Jsou výhodné nejen z hlediska výkonu, ale i údržby - jsou centralizovaně uložené, lze je lépe měnit při změnách datového modelu, konfigurace DB atd.

Modifikovatelné výsledky dotazu

Podporuje-li to daný DBMS, můžeme řádky vrácených tabulek modifikovat:

ResultSet result = stmt.executeQuery(
   "SELECT TEXT " +
   "FROM MESSAGES " +
   "WHERE ID > 10");

// posuň se na pátý řádek výsledku
result.absolute(5);

// změň hodnotu atributu/pole
result.updateString("TEXT", "Zmeneny text zpravy"); 

// proveď změny
result.updateRow();

Metadata

DBMS poskytne základní informace o

  • svých schopnostech (dostupných funkcích) a

  • údaje o příslušně databázi (metadata)

voláními, jako jsou:

DatabaseMetaData dbmd = con.getMetaData();

// základní údaje o DBMS
System.out.println(
   "DBMS: " +
   dbmd.getDatabaseProductName()  + ", " +
   dbmd.getDatabaseProductVersion() );

// údaje o driveru
System.out.println(
   "Driver: " +
   dbmd.getDriverName()  + ", " +
   dbmd.getDriverVersion() );

// dostupné funkce DBMS
   System.out.println("String functions: "+dbmd.getStringFunctions());
   System.out.println("TimeDate functions: "+dbmd.getTimeDateFunctions());
   System.out.println("Numeric functions: "+dbmd.getNumericFunctions());
   System.out.println("System functions: "+dbmd.getSystemFunctions());

Zpřístupnění datového zdroje přes JNDI

Moderní přístup k datovým zdrojům je založen na přidání další úrovně adresovací abstrakce:

  • místo URL databáze, jména a hesla se

  • prostřednictvím jmenné a adresářové služby (JNDI) najde datový zdroj - aplikační programátor ani předem neví, kde je zdroj fyzicky uložen, jaký DBMS se o něj stará

  • datový zdroj se zpřístupní nikoli jako Connection, ale ponovu jako javax.sql.DataSource

  • teprve z něj se získá spojení.

[Poznámka]Poznámka

JNDI služba je obvykle ve správě aplikačního (webového) serveru (Tomcat, jboss...)

Java Data Objects (JDO)

JDO - charakteristika

JDO je Java-centrická alternativa k tradičním způsobům zajištění perzistence dat:

  • JDBC (přístup z Javy k relačním datům)

  • serializace (základní technika převodu objektů - potenciálně libovolných - do binární, uložitelné, podoby)

JDO - forma

JDO je specifikace, která prochází tzv. Java Community Process (JCP) Program, blíže viz http://jcp.org.

Mají na ni tedy vliv i nezávislí vývojáři.

Její aktuální platná verze je 1.0.1, připravuje se 2.0.

Specifikace JDO 1.0.1 má 200 stran.

JDO - motivace

Motivací pro JDO bylo dát pohodlnější techniku (než JDBC a serializace) pro zachycení stavu běžných javových objektů v programu a možnost jeho obnovy.

JDO - struktura

JDO - implementace

Existuje několik open-source i komerčních implementací JDO:

Solametric Kodo JDO

komerční implementace JDO, dostupná na http://www.solarmetric.com/

Popis: Kodo JDO is SolarMetric's robust, high-performing, feature-rich implementation of the Java™ Data Objects specification for transparent persistence. Unlike many proprietary object/relational mapping tools, Kodo JDO provides access to relational databases through the JDO standard, enabling Java developers to use existing relational database technology from Java without needing to know SQL or be an expert in relational database design. It can be used with existing database schemas, or can automatically generate its own schema.

Castor JDO

open-source, free (BSD-like licence), dostupný na http://www.castor.org/jdo.html

TriActive JDO (TJDO)

open-source, free implementace, dostupná na http://tjdo.sourceforge.net/. Charakteristika:

Supports JDO 1.0.1. Implements the entire JDOQL query language, including several useful method enhancements. Auto-creates all necessary schema elements (tables, foreign keys, indexes) according to your app's classes and JDO metadata. Auto-validates expected schema structure at runtime, reducing failures from schema evolution. Can map Java classes to SQL views, and allows for direct SQL queries, to leverage SQL capabilities not normally accessible through JDO. Designed to be lightweight and fast.

JDO - informační zdroje

JDO - alternativy

Alternativou pro pohodlnou serializaci mnoha typů objektů do XML je např. open-source balík XStream, viz dále.

Serializace dat do XML

Serializace obecně - připomenutí

Javová třída může implementovat rozhraní java.io.Serializable, které

  • nepředepisuje žádné metody, ale zajistí, že

  • objekty dané třídy lze serializovat, tj. převést jejich obsah (proměnné) na binární (vnější) podobu zapsatelnou např. do souboru

  • inverzně lze zase objekty z této binární podoby deserializovat

Serializace

Při serializaci se standardně

  • převádějí do binární podoby všechny instanční proměnné

  • vyjma těch označených klíčovým slovem transient

Tak lze zajistit serializaci skutečně jen potřebných složek stavu objektu, zbytek se po deserializaci může "dopočítat".

[Poznámka]Poznámka

Typický příklad: symetrickou matici (např. podle hlavní diagonály) neukládáme celou, ale jen "jednu polovinu".

Serializace - metody

Požadujeme-li speciální chování (např. kvůli serializaci návazných/odkazovaných objektů), můžeme v objektu poskytnout metody:

private void writeObject(java.io.ObjectOutputStream out) throws IOException

realizuje zápis objektu do výstupního proudu - metodu si napíšeme sami

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

realizuje čtení objektu ze vstupního proudu - metodu si napíšeme sami

Serializační mechanizmus zajistí vytvoření "prázdného" objektu, ten pak naplníme metodou readObject.

Serializace do XML - vazba XML na Javu

Jednoduché nástroje serializace - XStream

Potřebujeme-li serializaci javových objektů jen na prosté účely typu

  • uložení a opětovné načtení konfigurace do/ze XML souboru

  • přenesení objektů jinému procesu, programu, na jiný stroj

pak je XStream pravděpodobně nejlepší volbou, pokud nám nevadí nepodpora non-ASCII znaků...

Jak funguje XStream

XStream je extrémně jednoduše a přímočaře použitelné API pro serializaci jakýchkoli objektů do XML.

Není třeba psát žádné popisovače, stačí vybrat objekt a poslat ho metodě toXML objektu serializátoru org.codehaus.xstream.XStream.

XStream - příklad, krok 1

Vytvoříme pole se zadaným počtem prvků, postupně do něj vřadíme nově vytvořené objekty Person a toto pole serializujeme.

public static int LEN = 10000;
public static void main(String[] args) {
   Person[] people = new Person[LEN];
   XStream xs = new XStream();
   xs.alias("person", Person.class);
   for(int i = 0; i < LEN; i++) {
      people[i] = new Person("Clovek "+i, i, i * 10);
   }
   // serialize
   String xml = xs.toXML(people);
   System.out.println(xml);

// uncomment the following code to test deserialization
/*
   Person[] secondPeople = (Person[])xs.fromXML(xml);
   for(int i = 0; i < secondPeople.length; i++) {
      increaseSalary(secondPeople[i], 20);
   }
*/
}

XStream - příklad, krok 2

Vytvořený soubor vypadá takto:

<person-array>
  <person>
    <name>Clovek 0</name>
    <age>0</age>
    <salary>0.0</salary>
  </person>
  <person>
    <name>Clovek 1</name>
    <age>1</age>
    <salary>10.0</salary>
  </person>
  <person>
    <name>Clovek 2</name>
    <age>2</age>
    <salary>20.0</salary>
  </person>
  ...

Hibernate

Hibernate

Hibernate

Kapitola 4. Aplikační vrstva javových aplikací - řízení toku, správa komponent. Pokročilé zásady a metodiky návrhu aplikační logiky - Design by Contract, Inversion of Control, Aspect-oriented Programming. Kontejnery, aplikační servery.

Obsah

Aplikační vrstva javových aplikací
Aplikační vrstva javových aplikací
Design by Contract
Design by Contract - návrh podle kontraktu
DBC - jak dosáhnout
DBC - nástroj jass
Postup při práci s jass
Odkazy
Inversion of Control (IoC)
Nezbytné pojmy z komponentních systémů
IoC - Motivace
Tradiční řízení životního cyklu komponent
IoC - Hlavní princip
IoC - Možné podoby
Interface Injection
Setter Injection - komponenta
Setter Injection - popis komponenty
Setter Injection - výhody/nevýhody
Constructor Injection
Constructor Injection - příklad komponenty
Použití IoC - kontejnery
Aspect Oriented Programming (AOP)
AOP - Motivace
AOP - Motivační příklad
AOP - Principy
Kontejnery a aplikační servery
Kontejnery a aplikační servery
Java Management extension (JMX)
Co je JMX
Co řídí JMX
Principy JMX
Který objekt (komponentu) jako JMX?
Úrovně JMX modelu
Ovládané zdroje
Jak se zdroje ovládají
MBean
Co obsahují/zpřístupňují rozhraní MBean
Typy MBean
Aplikační rámec Tammi - případová studie
Charakteristika Tammi
Příklad jednoduché komponenty typu MBean
Skriptování v javovém prostředí - BSF
Co je skriptování?
Proč skriptovat?
Proč skriptovat právě teď?
Bean Scripting Framework
BSF - co nabízí
BSF - typické použití
BSF - download a další info
Skriptování v javovém prostředí - Groovy
Groovy - motivace
Stažení
Instalace
Spuštění
Příklad - iterace
Příklad - mapa
Příklad - switch
Řízení a sledování aplikací - protokolování
Protokolování (logging)
Protokolování - výhody
Protokolování - možnosti v Javě
Protokolování - API
Protokolování - příklad

Aplikační vrstva javových aplikací

Aplikační vrstva javových aplikací

Aplikační vrstva javových aplikací

Design by Contract

Design by Contract - návrh podle kontraktu

Nejde o nic jiného, než o zajištění, aby výsledný navržený program splňoval specifikaci, tj.:

  • aby pro každý atomický, zvenčí viditelný/volatelný kus kódu (typicky metoda) byly specifikovány vstupní a výstupní podmínky

  • a aby jejich platnost byla za běhu zaručena

  • mezi zadavatelem (tj. analytikem, příp. zákazníkem) a návrhářem tak vzniká

  • dohoda (contract), že specifikace bude dodržena

DBC - jak dosáhnout

K dosažení tohoto ideálního stavu vede budto čistě formální cesta:

  • specifikace zmíněných podmínek matematickými prostředky a

  • formální dokazování korektnosti

Dále zmiňované nástroje však toto nedokážou; omezují se na běhovou kontrolu platnosti předpsaných podmínek

DBC - nástroj jass

jass je preprocesor javového zdrojového textu. Umožňuje ve zdrojovém textu programu vyznačit podmínky, jejichž splnění je za běhu kontrolováno.

Podmínkami se rozumí:

  • pre- a postconditions u metod (vstupní a výstupní podmínky metod)

  • invarianty objektů - podmínky, které zůstávají pro objekt v platnosti mezi jednotlivými operacemi nad objektem

Postup při práci s jass

Postup práce s jass:

  • stažení a instalace balíku z http://csd.informatik.uni-oldenburg.de/~jass/

  • vytvoření zdrojového textu s příponou .jass, javovou syntaxí s použitím speciálních komentářových značek

  • takový zdrojový text je přeložitelný i normálním překladačem javac, ale v takovém případě ztrácíme možnosti jass

  • proto nejprve .jass souboru převedeme preprocesorem jass na javový (.java) soubor

  • ten již přeložíme javac a spustíme java, tedy jako každý jiný zdrojový soubor v Javě

  • z .jass zdrojů je možné vytvořit také dokumentaci API obsahující jass značky, tj. informace, co kde musí platit za podmínky atd. - vynikající možnost!

Inversion of Control (IoC)

Nezbytné pojmy z komponentních systémů

Uvádíme pragmaticky jen to, co je potřeba zde (pro potřeby IoC), nechápat jako komplexní terminologii.

komponenta (component)

objekt poskytující navenek ucelenou funkcionalitu (část aplikační nebo pomocné logiky)

komponenta je obvykle chápána jako "velký objekt" nebo graf více objektů s vnějším rozhraním ("fasádou")

komponenta je sice do jisté míry samostatná, ale většinou nežije nezávisle; za běhu potřebuje návaznosti na další komponenty nebo hostující rámec (kontejner)

kontejner (container)

objekt, v němž jsou za běhu aplikace uloženy a spravovány komponenty (objekty)

kontejner dokáže většinou komponenty i vytvářet a poskytovat odkazy na ně (vyhledávat je)

IoC - Motivace

V komponentních systémech bývá tradičním problémem zajistit správnou inicializaci a provoz komponent závislých na ostatních.

  • jak závislosti popsat

  • jak získat objekty (komponenty), na nichž vytvářená komponenta závisí

  • jak tuto komponentu vytvořit

  • jak závislosti předat ("injektovat") do ní

Tradiční řízení životního cyklu komponent

Co je třeba udělat při nasazení jedné nové komponenty

  1. Připravit komponenty, na nichž "ta moje" závisí

  2. Vytvořit "noji komponentu"

  3. Nastavit závislosti

Postup vypadá přímočaře, ale je bohužel rekurentní... v bodě 1 (připravit komponenty...) se opakuje rekurentně celý postup

IoC - Hlavní princip

V Inversion of Control obracíme tento (pro komponentního programátora) nepraktický, obtížný postup.

O řešení závislostí se postará rámec (kontejner), komponenta pouze deklaruje na čem závisí.

IoC - Možné podoby

Historicky se postupně vyvinuly tři přístupy k "injektáži" potřebných závislostí; tedy k IoC:

  • Interface Injection

  • Setter Injection

  • Constructor Injection

Blíže viz popis k IoC v systému (rámci) vraptor a následující slidy.

Interface Injection

Komponenta MUSÍ IMPLEMENTOVAT určité, rámcem/kontejnerem dané rozhraní (příklad z článku Intro. to AOP):

import org.apache.avalon.framework.*;

  public class JDBCDataManger implements Serviceable {
    DataSource dataSource;
    public void service (ServiceManager sm) 
          throws ServiceException {
      dataSource = (DataSource)sm.lookup("dataSource");
    }
    
    public void getData() {
      //use dataSource for something
    }
}

Nevýhoda: musí implementovat dané rozhraní, nelze vyvíjet zcela nezávisle.

Setter Injection - komponenta

Komponenta je jako objekt JavaBean, má setXXX metody:

public class JDBCDataManger {
  private DataSource dataSource;
  
  public void setDataManager(DataSource dataSource {
    this.dataSource = dataSource;
  }
  
  public void getData() {
      //use dataSource for something
  }
}

Setter Injection - popis komponenty

Rámec (kontejner), např. Spring musí vědět, jak komponentu vytvořit a na čem závisí:

<bean id="myDataSource" 
  class="org.apache.commons.dbcp.BasicDataSource" >
  <property name="driverClassName">
    <value>com.mydb.jdbc.Driver</value>
  </property>
  <property name="url">
    <value>jdbc:mydb://server:port/mydb</value>
  </property>
  <property name="username">
    <value>root</value>
  </property>
</bean>

a druhá komponenta:

<bean id="dataManager" 
  class="example.JDBCDataManger">
  <property name="dataSource">
    <ref bean="myDataSource"/>
  </property>
</bean>

Setter Injection - výhody/nevýhody

Oproti Interface Injection: netřeba implementovat rozhraní

Je ale nezřetelné, které setXXX metody jsou pro účely nastavení závislostí přes Setter Injection a které ne.

Constructor Injection

Odpovídá přístupu "Good Citizen" (označení zavedl J. Bloch ze Sun):

  • objekt je po vytvoření (a aplikaci konstruktoru) plnohodnotný, plně inicializovaný, platí pro něj všechny invarianty, lze jej použít

Constructor Injection - příklad komponenty

public class JDBCDataManger {
  private DataSource dataSource;
  
  public JDBCDataManger(DataSource dataSource) {
    this.dataSource = dataSource;
  }
  
  public void getData() {
      //use dataSource for something
  }
}

Použití IoC - kontejnery

Existují jednoduché (lightweight) kontejnery pro nasazení a provoz komponent s využitím IoC.

Tyto kontejnery mnohdy neumí nic navíc, jde jen o základní správu komponent.

Příkladem je PicoContainer a Spring, který je však komplexnější (a složitější).

Aspect Oriented Programming (AOP)

AOP - Motivace

  • Programový kód rozsáhlejších soudobých systémů je složitý, nepřehledný, nesnadno udržovatelný.

  • U systémů jsou často implementovány mimofunkční požadavky: protokolování, zabezpečení, optimalizace.

  • Pokrytí těchto požadavků jde napříč s požadavky funkčními - současné splnění vede nezřídka ke kombinatorické explozi a (téměř) exponenciálnímu nárůstu velikosti kódu.

  • Kód je nečitelný a ještě obtížněji udržovatelný.

  • I rozšiřování nelze většinou provést lokálně, nezřídka je jím zasaženo více částí kódu.

AOP - Motivační příklad

Příklad převzatý z weblogu Jablok Pavla Kolesnikova (typický kód aplikační logiky):

public class KusAplikacniLogiky extends ObecnejsiKus {
  // data tridy;
  // jina pomocna data;

  // pretizeni rodicovskych metod

  public void provedNecoPodstatneho () {
    // autentizace
    // autorizace

    // dalsi nezajimavy kod
    // logovani zacatku operace

    // vlastni aplikacni logika — konecne!

    // logovani ukonceni operace
    // treba jeste neco
  }
}
  • stále se opakující úkony na začátku před vlastní realizací "užitečné práce" a po ní

  • aplikační logika tvoří jen zlomek rozsahu kódu

AOP - Principy

Překlad článku Graham O'Regana Introduction to Aspect-Oriented Programming na onjava.com nastiňuje hlavní principy:

  • AOP umožňuje přidat do statického OO modelu programu (třídy) dynamické aspekty - např. ovlivňovat (vstupovat do) volání metod.

  • Např. servlet očekává vstup z webového formuláře, naváže data z formuláře do vytvořeného datového objektu, ten zpracuje aplikační logikou a výsledek prezentuje.

  • Kromě toho ale musí řešit:

    • ošetření výjimek

    • zabezpečení přístupu

    • protokolování

Kontejnery a aplikační servery

Kontejnery a aplikační servery

Kontejnery a aplikační servery

Java Management extension (JMX)

Co je JMX

  • JMX je rozhraním definujícím strukturu a chování jednotlivých prvků systému schopného snadné a standardizované správy, monitoringu....
  • JMX je v současnosti řadou výrobců (i open-source vývojářů) považováno za nejlepší rozhraní pro správu takových systémů.
  • JMX je formálně výsledkem práce JSR003.

Co řídí JMX

Přes JMX se řídí:

  • moduly
  • kontejnery, v nichž jsou moduly hostovány/provozovány
  • zásuvné moduly (plug-ins)

Principy JMX

  • Komponenty jsou v JMX deklarovány jako _lužby MBean_(MBean services).
  • JMX následně umožní zavedení a správu těchto komponent.

Který objekt (komponentu) jako JMX?

Vhodnými kandidáty na JMX (MBeans) jsou takové komponenty, které:

  • Interagují s (jsou ovládány) objekty z jiných vrstev aplikace.
  • Objekt má stav, který má být sledován/řízen.
  • Objekt je konfigurován nezávisle při startu/za běhu aplikace.

Úrovně JMX modelu

Model systému řízeného JMX zahrnuje:

Instrumentation
zdroje, jež jsou spravovány
Agents
kontrolery (ovladače) těchto zdrojů
Distributed Services
služby, jimiž (koncové) aplikace pro správu komunikují s výše uvedenými agenty

Ovládané zdroje

Přes JMX se může řídit prakticky cokoli v javovém systému:

  • (celou) aplikaci
  • komponentu služby
  • zařízení

Jak se zdroje ovládají

JMX ovládá zdroje prostřednictvím tzv. _rapperu_ který:

  • vystavuje (zpřístupňuje) vlastnosti spravovaných objektů
  • díky tomu může externí, standardizovaný nástroj, přistupovat k spravovanému objektu

Jaké podoby může wrapper nabývat?

MBean

MBean
javový objekt implementující jedno či více standardních MBean rozhraní a je konstruován podle odpovídajících návrhových vzorů

Co obsahují/zpřístupňují rozhraní MBean

  • hodnoty atributů přístupných prostřednictvím jména atributů
  • operace, které lze volat
  • notifikace událostí, které zde mohou vzniknout
  • konstruktory MBean třídy

Typy MBean

Standard MBean
pouze odpovídají JavaBean konvencím a staticky definovaným (JMX) rozhraním pro správu
Dynamic MBean
...
Open MBean
...
Model MBean
...

Aplikační rámec Tammi - případová studie

Charakteristika Tammi

  • Komplexní (webový) aplikační rámec
  • dostupný na http://tammi.sf.net
  • Jedna z nejucelenějších aplikací JMX - používá se zde "na všechno"

Příklad jednoduché komponenty typu MBean

Komponenta koncipovaná jako MBean je často vytvářena takto:

  1. Je vytvořen (nebo existuje) "běžný" bean s požadovanou funkcionalitou.
  2. Je sestaveno rozhraní typu MBean, které bude navenek reprezentovat tuto funkcionalitu.
  3. Je sestavena třída (wrapper, adaptér), který rozšiřuje původní bean a implementuje toto rozhraní.

FibonacciCounter.java - původní komponenta

CounterMBean.java - rozhraní

Counter.java - třída implementující rozhraní

Skriptování v javovém prostředí - BSF

Co je skriptování?

Co odlišuje skriptování od "ostatních" pg. jazyků?

  • Rychlý vývoj, přímočarý životní cyklus SW: napiš - spusť (- potom odlaď)
  • Obvyklé dynamicky (až za běhu) typovaný jazyk, nevyžaduje deklarace proměnných, definice tříd...
  • Jazyk je často kombinovatelný s běžnými pg. jazyky - lze volat jejich metody, používat knihovny...
  • Prostá, obvykle intuitivní, syntaxe
  • Mnohdy jde de-facto o syntaktický klon "plného" jazyka - mj. aby se snáze učilo
  • Obvykle malé nároky na udržovatelnost, dokumentovatelnost, rozšiřitelnost vzniklých SW výtvorů
  • Jednoduché věci jdou napsat jednoduše, složité složitě, nepěkně nebo pořádně vůbec...

Proč skriptovat?

Kdy obvykle (nejen v Javě) cítíme potřebu skriptovat?

  • Když zkoušíme, "hrajeme si", testujeme narychlo vytvořené věci
  • Hledáme vhodné hodnoty parametrů, hezký vzhled něčeho
  • Potřebujeme ovládat konfiguraci složitější aplikace - které objekty se mají vytvořit, jak je propojit...

Proč skriptovat právě teď?

Proč je potřeba skriptovat silná právě dnes, když je tolik dokonalých programovacích jazyků s rychlými překladači?

  • SW architektury jsou složité, je třeba je - mnohdy dynamicky - (re)konfigurovat.
  • Často integrujeme - a při integraci je nutné zkoušet, ladit, ale i konfigurovat.
  • Máme málo času přemýšlet nad složitou architekturou "úplné" aplikace, chceme rychle něco navrhnout a vyzkoušet nebo i používat.
[Poznámka]Poznámka

Takové rychlovýtvory nezřídka mívají delší životnost než složitě a dlouho budované "pořádné" aplikace - přicházejí rychle a v pravý čas!

Bean Scripting Framework

Bean Scripting Framework (BSF) je projektem jakarta.apache.org, původně však vytvořený v IBM T.J.Watson Laboratories (jako produkt "alphaWorks").

Jedná se o rámec umožňující:

  • přístup z javových aplikací ke skriptování v mnoha běžných skript. jazycích (Javascript, Python, NetRexx ...)
  • naopak ze skriptů je možno používat javové objekty
[Poznámka]Poznámka

To mj. dovoluje "save of investment" do stávajících skriptů - i z plnohodnotného prostředí (Java) je lze volat!

BSF - co nabízí

BSF obsahuje dvě hlavní komponenty:

BSFManager
spravuje javové objekty, k nimž má být ze skriptů přístup. Řídí provádění těchto skriptů.
BSFEngine
rozhraní, API, které musí hostující skriptovací jazyk nabídnout, aby jej bylo možné v rámci BSF pužívat.

BSF - typické použití

  • je možné pouze instanciovat jeden BSFManagera
  • z něj přes BSFEnginespouštět skripty s možností přístupu k objektům v kontextu manažeru.

BSF - download a další info

Skriptování v javovém prostředí - Groovy

Groovy - motivace

  • Již delší dobu pro Javu existuje rámec BSF podporovaný řadou skriptovacích jazyků.
  • Autorům Groovy se však většina z nich zdála syntakticky "těžko stravitelná" pro javového programátora, který "málo, ale občas přece" potřebuje skriptovat.
  • Groovy je tedy vytvořet v Javě a na míru pro javové programátory.
  • Nabízí velmi příjemnou a intuitivní syntaxi, hezkou konzolu pro spouštění atd.
  • Skript se překládá do javového bajtkódu, je tedy na běhové úrovni dobře interoperabilní s Javou.

Stažení

  • Groovy najdeme na http://groovy.codehaus.org.
  • Plná, tj. zdrojová i binární distribuce má vč. dokumentace a příkladů přes 56 MB!!!
  • Je zároveň hezkou ukázkou netriviální projektu řízeného Mavenem.

Instalace

  • rozbalit distribuci do zvoleného adresáře
  • nastavit systémovou proměnnou GROOVY_HOME na tento adresář
  • přidat $GROOVY_HOME/bin do PATH

Spuštění

Tři základní způsoby:

groovysh
řádkový Groovy-shell
groovyConsole
grafická (Swing) konzola Groovy
groovy SomeScript.groovy
přímé (neinteraktivní) spuštění skriptu pod Groovy

Příklad - iterace

Iterace přes všechna celá čísla 1 až 10 s jejich výpisem:

for (i in 1..10) {
  println "Hello ${i}"
}

Příklad - mapa

Definice mapy (asociativního pole) a přístup k prvku:

map = ["name":"Gromit", "likes":"cheese", "id":1234]
assert map['name'] == "Gromit"

Příklad - switch

Řízení toku pomocí switch s velmi bohatými možnostmi:

x = 1.23
result = ""
switch (x) {
    case "foo":
        result = "found foo"
        // lets fall through    
    case "bar":
        result += "bar"    
    case [4, 5, 6, 'inList']:
        result = "list"
        break
    case 12..30:
        result = "range"
        break
    case Integer:
        result = "integer"
        break
    case Number:
        result = "number"
    break    default:
        result = "default"
}
assert result == "number"

Řízení a sledování aplikací - protokolování

Protokolování (logging)

Protokolování je základní činností sledující běh software v

  • testovacím i

  • ostrém nasazení.

Protokolování - výhody

Protokolování má oproti klasickým přístupům

  • System.out.println nebo o něco lepším

  • System.err.println

jasné výhody:

  • snadná konfigurovatelnost

  • nezaměnitelnost s jinými (neladicími) výstupy programu

  • možnost vazby na zasílání zpráv mailem, ukládání do souborů, databáze

Protokolování - možnosti v Javě

V zásadě dva možné přístupy:

  • použít standardní API

  • použít API daného aplikačního prostředí (ap. serveru)

Standardní API je však často ap. serverem také podporováno a má jasné výhody:

  • je známé, existuje široká komunita se zkušenostmi

  • obsluhu obvykle již sami známe

Protokolování - API

Existuje několik "standardních" protokolovacích API:

  • od Java 1.4: balík java.util.logging

  • již dříve nezávislé open-source řešení log4j

Obě řešení jsou srovnatelná, log4j je o něco elegantnější a propracovanější. Nejlépe (pokud to stačí) je použít zastřešujícího API:

  • balík Apache Commons Logging

Protokolování - příklad

Existuje několik "standardních" protokolovacích API:

  • od Java 1.4: balík java.util.logging

  • již dříve nezávislé open-source řešení log4j

Obě řešení jsou srovnatelná, log4j je o něco elegantnější a propracovanější. Nejlépe (pokud to stačí) je použít zastřešujícího API:

  • balík Apache Commons Logging

Kapitola 5. Prezentační vrstva javových webových aplikací. Přístupy - šablony, dekorátory. Velocity, WebMacro, Sitemesh, Freemarker. Nové přístupy - AJAX

Prezentační vrstva webových aplikací

Prezentační vrstva webových aplikací

Prezentační vrstva webových aplikací

AJAX - Asynchronous JavaScript and XML

Webové aplikace - důvody pro

Rozšíření webových aplikací na úkor desktopových má své důvody:

  • Snadnější údržba (opravy či aktualizace verzí pocítíme jako uživatelé, ne jako správci).

  • Většinou snadnější vývoj díky platformové nezávislosti kombinací HTTP, HTML, grafických formátů (a příp. JavaScriptu).

  • Vše dobře ladí s centralizací dat a jejich zpracování na serveru.

  • I starosti se zabezpečením (safety & security) jsou centralizovány.

Webové aplikace - důvody proti

Tradiční webové aplikace trpěly typickými nedostatky oproti klasickým desktopovým aplikacím:

  • komunikace klient-server byla vždy inicována ze strany klienta a to většinou akcí uživatele - klikem na odkaz, stiknem tlačítka...

  • většina operací (aplikační logiky) musela být na serveru (s drobnými výjimkami - validace vstupu, drobné změny v GUI...)

  • zvyšovalo to zátěž sítě a hlavně ztěžovalo práci

  • jsou starosti s nekompatibilitou interpretace HTML a zejména skriptů (i JavaScriptu) na různých platformách i prohlížečích.

Přístup AJAX - Asynchronous JavaScript and XML

Koncepce AJAX je vybudována na principech webových aplikací, které generují a používají na straně klienta (tj. v prohlížeči) speciální javascriptové techniky, jež:

  • asynchronně komunikují se stranou serveru a

  • vyměňují si XML data

  • na straně klienta je skriptem modifikován DOM model dokumentu

Výhody

  • Uživatel nemusí stále klikat, aby získal odezvu na své akce: výběry ze seznamů, vpisování do textových polí, pohyby po obrázcích (např. mapách) atd.

  • Není nutné při sebemenší aktualizaci generovat na straně serveru a následně načítat a zobrazovat celou stránku.

Kde je použito?

Nejznámnějšími místy intenzivně využívajícími principy AJAX jsou služby Google:

  • Google Suggest (FAQ)- při vyhledávání jsou uživateli nabízeny tipy (klíčová slova), na co se může ptát

  • Google Gmail (popis)- jsou nabízeny adresy příjemců zpráv, automaticky je aktualizován obsah mailboxu...

  • Google Maps - při pohybu v mapě se automaticky objevují nové části mapy.

To ale nejsou aplikace jediné, mezi další patří i české:

  • slovnik.seznam.cz - při vkládání slova pro překlad se objevují tipy, co zadat.

  • Manuel Kiessling’s open-source ARSC (A Really Simple Chat) - chat založený na HTTP komunikaci

  • KnowNow’s SpeedReader

Jak pracuje?

AJAX není jednou technologií, ale spočívá v použití kombinace (známých a zavedených) technologií a standardů:

  • HTML / XHTML a CSS pro prezentaci informací

  • JavaScript pro modifikaci Document Object Modelu (DOM) na klientovi

  • XMLHttpRequest pro (asynchronní) výměnu dat se serverem.

AJAX ve spojení s J2EE

Server dev.java.net nabízí v rámci Java BluePrints Solutions Catalog sekci:

Kapitola 6. Komplexní podpora webových aplikací. Webové rámce.

Webové aplikační rámce

Osnova

  • Webový rámec a jeho architektura

  • Funkcionalita webových rámců

  • Výstavba aplikací nad webovými rámci

Webový rámec

  • Více či méně ucelené prostředí pro tvorbu (případně i nasazení) webových aplikací středního rozsahu

  • Není to knihovna!

  • Využívá "The Hollywood Principle": Do Not Call Us, We Will Call You!

  • Rámec "funguje sám", my jej modifikujeme a doplňujeme

  • Budeme diskutovat javové rámce

Třívrstvá architektura

Vrstvy "od uživatele dolů":

  1. prezentační vrstva - ve webových aplikacích HTML, CSS, JavaScript,... na klientovi (prohlížeči): JSP, servlety, XSLT, JSTL, JSF, šablony...

  2. aplikační logika - javové objekty, JavaBeans, EJB...

  3. databázová vrstva - DBMS dostupný přes JDBC

Koncepce MVC

  • Model - objekty/data a jejich obslužné metody realizující vlastní aplikační logiku

  • View - pohled na data - prezentace, vstup od uživatele

  • Controller - řídí tok zpracování - kdy se aktivuje jaká metoda modelu, jaký pohled se uplatní na výsledek,...

Přednosti MVC

  • Nezávislost modelu na zbylých částech

  • Jeho znovupoužitelnost

  • Na modelu a pohledech lze pracovat do jisté míry nezávisle - jsou požadovány jiné schopnosti (programátor vs. designér)

  • Controller mnohdy programovat ani nemusíme - díky (webovým) rámcům!

Javové webové aplikace

Javové webové aplikace

  • Základem je Java Servlet API

  • specifikuje Servlety, stránky JSP, knihovny značek, filtry, popisovače...

  • Jeho implementace jsou volně dostupné a dobře prozkoumané

Javové webové aplikace (2)

Java Servlety:

  • javové třídy rozšiřující typicky abstraktního předka javax.servlet.http.HttpServlet

    stránky JSP:

  • podobný princip jako ASP, PHP

  • při požadavku se přeloží do servletu

Javové webové aplikace (3)

  • knihovny značek (Tag Libraries): pro JSP lze zadefinovat vlastní XML značky obsluhované javovým kódem a ty na stránkách JSP používat

  • filtry: než je HTTP požadavek předán servletu (JSP), může být filtrován, filtr je podobný servletu, lze filtrovat i vygenerovanou odpověď

Javové webové kontejnery

Kontejnery (Java Web Containers):

  • servery (programy) hostující javové webové aplikace

Příklady (volně dostupné):

  • Apache (Jakarta) Tomcat

  • Jetty

  • LWS, Bajie, ...

Rozdíl oproti aplikačním serverům:

  • většinou nepodporují plnou specif. J2EE

  • nehostují EJB

Funkcionalita webových rámců

Oddělení prezentační vrstvy

Oddělení prezentační vrstvy - většinou prostřednictvím jazyka šablon (template language) jako jsou:

  • Velocity, WebMacro, FreeMarker, RIFE ...

  • nebo JSTL (std. knihovna značek)

  • moderně přes JSF (Java Server Faces)

  • napodobují klasické "desktopové" GUI v prostředí webové aplikace

  • případně transformace XSLT

Oddělení prezentační vrstvy (2)

Oddělení prezentační vrstvy

  • Šablona Velocity - stránka jednoduchého weblogu

<html><head>
  <title>#showWebsiteTitle()</title>
  <style type="text/css">#includePage("_css")</style>
  #showRSSAutodiscoveryLink()
</head>
<body><div id="Content">
    <center>
      <h1>#showWebsiteTitle()</h1> 
      <p class="descrip">#showWebsiteDescription()</p> 
      #showWeblogCategoryChooser()<br>
    </center>            
    #showWeblogEntries("_day" 15)
    <hr />
    #showReferers( 40 25 )
</div></body></html>

Oddělení prezentační vrstvy (3)

  • Stránka využívající JSF

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-faces" 
  prefix="s" %> 
<f:use_faces>
  <s:form action="/listFlights">
  <h:input_text id="fromCity"       
             valueRef="FlightSearchForm.fromCity"/>
  <h:input_text id="toCity"  
             valueRef="FlightSearchForm.toCity"/>
<h:command_button id="submit" action="success" label="Submit" commandName="submit" />
   <h:command_button id="reset" action="reset" label="Reset" 
                     commandName="reset" />
   <s:errors/>
   </s:form>
</f:use_faces>

Funkcionalita webových rámců

  • Správa zabezpečení - např. deklarativní nařízení přihlašování

  • použití nastavení Java Security Manageru

  • pak lze na serveru hostovat i nedůvěryhodný "zákaznický" kód

  • lze také použít filtry (jakási vnitřní "autentizační proxy")

  • Vše směřuje k deklarativní specifikaci zabezpečení - snadněji se udržuje

Správa zabezpečení - příklad

Příklad konfigurace Java Security Manageru (Apache Tomcat 5):

The permission granted to your JDBC driver
grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
    permission java.net.SocketPermission "dbhost.mycompany.com:5432", connect";
};...
// These permissions apply to the container's core code, plus any additional libraries installed in the "server" directory
grant codeBase "file:${catalina.home}/server/-" {
        permission java.security.AllPermission;
};

Validace uživatelských vstupů

Řada rámců podporuje deklarativní specifikaci uživatelských vstupů

  • datový typ, formát, přípustné rozmezí hodnot...

  • a jejich dekódování

  • znakové sady, různé národní zvyklosti

Pokročilé rámce:

  • řízení toku při vyplňování formulářů (průvodci jako u desktopových GUI)

  • automatické generování fyz. podoby form.

Příklad specifikace zpracování uživ. vstupů - rámec Struts

<form-validation>
   <formset>
      <form name="addSubjectForm">
         <field property="subjID" 
                depends="required" page="1">
             <arg0 key="admin.subject.missing.ID"/>
         </field>
         <field property="subjName" 
                depends="required" page="1">
             <arg0 key="admin.subject.missing.name"/>
         </field>
         <field property="groupID" 
                depends="required" page="2">
             <arg0 key="admin.subject.missing.groupID"/>
         </field>
      </form>
      <form name="addTaskForm">...

Udržování informací o relaci

Mezi jednotlivými interakcemi s uživatelem je uchován stav dané relace -

  • Překlenuje bezestavovost HTTP

  • V javových aplikacích pomocí objektů javax.servlet.http.HttpSession

Řízení toku aplikace

  • Rozsáhlejší aplikace mívají složitou navigační strukturu

  • v MVC modelu řídí navigaci Controller

  • navigace bývá v rámcích popisována deklarativně

Příklad řízení toku - Struts

<!-- Action Mapping Definition -->
<action-mappings>
  <!-- List Flights action -->
  <action path="/listFlights"
     type="foo.bar.FlightSearchAction"
     name="FlightSearchForm"
     scope="request"
     input="/faces/FlightSearch.jsp">
     <forward name="success" path="/faces/FlightList.jsp"/>
  </action>
</action-mappings>

Zotavení z chyb

  • Opět deklarativně bývá popsáno řízení toku po vzniku chybového stavu (výjimky)

  • Umožňuje bezpečně pokrýt i neočekávané chyby a zaznamenat je, poslat informaci správci...

Záznamy o událostech (logging)

Cíl:

  • S minimálním "obtěžováním" programátora zajistit kontrolu nad chodem aplikace ve fázi tvorby, ladění i ostrého provozu

Java nabízí několik "logging API":

  • od Java 1.4: balík java.util.logging

  • kdekoli: balíky log4j

  • zastřešující: Jakarta Commons Logging

Pomocí Aspect-oriented Programming lze logování řešit ještě méně invazivně

Internacionalizace a lokalizace

Rozlišujeme:

  • Internationalization (i18n)

  • Localization (l10n)

    Co znamenají národní zvyklosti:

  • texty v nabídkách, ovládacích prvcích,...

  • formáty výpisu data, času, měny, vícemístných a desetinných čísel

  • lexikografické řazení

Internacionalizace a lokalizace - příklad

<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<c:if test="${lang==null}">
 <fmt:setBundle basename="com.heaton.bundles.Forum" 
    var="lang" scope="session"/>
</c:if>
<c:if test="${param.lang!=null}">
 <fmt:setLocale value="${param.lang}"/>
 <fmt:setBundle basename="com.heaton.informit.I18NBundle" 
    var="lang" scope="session"/>
 <c:redirect url="index.jsp"/>
</c:if>
<html><head><title>I18N Example</title></head>
<body>
    <h1><fmt:message key="login.pleaselogin" bundle="${lang}"/></h1>
    <form method=post action=main.jsp>
        <fmt:message key="login.uid" bundle="${lang}"/><input name=uid><br/>
        <fmt:message key="login.pwd" bundle="${lang}"/><input name=pwd><br/>
        <input type="submit" name="action" value="<fmt:message 
        key="login.title" bundle="${login}"/>">
    </form>
    <h1><fmt:message key="login.language" bundle="${lang}"/></h1>
    <ul>
        <li><a href="index.jsp*lang=en">
        <fmt:message key="login.english" bundle="${lang}"/>(English)</li>
        <li><a href="index.jsp*lang=es">
        <fmt:message key="login.spanish" bundle="${lang}"/>(Spanish)</li>
    </ul>
</body></html>

Zajištění perzistence objektů

  • Objektový model v paměti vs. data na discích (v databázi)

  • Rámce do jisté míry vzájemné převody automatizují

  • Většinou používají osvědčený produkt třetí strany - např. Hibernate, POJO

Škálovatelnost a distribuovanost

  • Výkon aplikace nelze zvyšovat pouze hardwarovými prostředky nebo optimalizací

  • Zejména dnes je levnějším řešením použít svazek (cluster) "běžně výkonných" počítačů namísto jednoho supervýkonného

  • Více zatížená aplikace musí být schopna výkon škálovat

Škálovatelnost a distribuovanost

Řešením jsou tzv. aplikační servery

  • poskytují middleware: komplexní prostředí pro běh rozsáhlých (podnikových) aplikací

  • míří nad schopnosti běžných webových rámců - ty ale většinou podporují/využívají

Podpora vývojovými prostředími

  • Eclipse (+Struts Studio) volně dostupný

  • Borland JBuilder (+InternetBeans Express)

Přehled rámců

Shrnutí

  • Webové rámce usnadňují tvorbu středně rozsáhlých aplikací s webovým rozhraním

  • Realizují oddělení jednotlivých vrstev, jsou postavené na koncepci MVC

  • Programátorovi nabízejí infrastrukturu, která "funguje sama" a on ji doplňuje

  • Kromě toho poskytují řadu dalších drobných služeb

Kapitola 7. Enterprise JavaBeans

Enterprise JavaBeans

Enterprise JavaBeans

Enterprise JavaBeans

Kapitola 8. Systémy řízení zpráv, Java Messaging Service (JMS) API

Systémy řízení zpráv, Java Messaging Service (JMS) API

Systémy řízení zpráv - motivace

Svět podnikových (ale i jiných) IS často vyžaduje integrovat stávající systémy.

Možností, jak integrovat je více, liší se např. v míře/těsnosti vazby mezi jednotlivými systémy. Extrémy jsou:

  • těsná vazba (tight coupling) - systémy "o sobě ví všechno" (API), jsou na sobě závislé, často se musí výrazně modifikovat, aby mohly spolupracovat

  • volná vazba (loose coupling) - systémy "o sobě neví skoro nic", jsou nezávislé

Systémy řízení zpráv - výhody

Typickým příkladem a jedním směrem moderních integrujících technologií jsou systémy řízení zpráv.

Oproti jiným integračním technologiím mají tyto přednosti:

  • nevyžadují přiliš přebudovávat stávající aplikace proto, aby mohly spolupracovat;

  • nezpůsobují úzkou vazbu integrovaných systémů (systémy jsou tzv. loosely coupled);

  • jako odesílatelé zprávy nemusíme vůbec tušit, jak ji příjemce zpracuje, stačí dohodnout:

    • dohodnout formát

    • znát cílovou adresu zprávy

Systémy řízení zpráv - principy

Systémy řízení zpráv slouží ke správě výměny zpráv mezi softwarovými systémy nebo komponentami.

  • komunikace je peer-to-peer, systém řízení zpráv zajišťuje infrastrukturu

  • komponenty (systémy), které chtějí zasílat/přijímat zprávy, k tomu využívají služeb agentů (kteří jsou součástí API systémů řízení zpráv)

Systémy řízení zpráv - standardy

Javovou podobou rozhraní k systému řízení zpráv je Java Messaging Service (JMS) API, jehož historie sahá do roku 1998, současná verze je 1.1. (z r. 2002).

JMS je poměrně malé rozhraní, které nenutí programátora studovat příliš mnoho konceptů - je jednoduché.

JMS umožňuje komunikaci, která je:

asynchronní

zpráva je odeslána konzumentovi, který nemusí být stále "on-line"; vybere si zprávu, až se připojí

spolehlivá

systém zajistí perzistentní ukládání zpráv do doby, než jsou příjemcem přečteny; zajistí, že jsou přečteny právě jednou

JMS - kdy použít?

Možné důvody, proč JMS:

  • chceme propojovat komponenty bez znalostí jejich API

  • chceme robustní systém: je možný nezávislý souběžný provoz komponent

  • zasílání zpráv a čekání na odpověď je asynchronní - proces čekat nemusí (není to tedy request/response výměna)

JMS - co nabízí

Současná verze JMS nabízí:

  • rozhraní pro tvorbu klientů k (i jiným) systémům řízení zpráv

  • rozhraní Message-driven Beans

JMS - architektura

Aplikace JMS sestává z těchto relevantních entit:

JMS Provider

poskytovatel infrastruktury zasílání zpráv vč. administrace

JMS Clients

klienti produkující nebo konzumující zprávy

Messages

objekty - zprávy

Administered objects

typickými reprezentanty jsou předkonfigurované tovární objekty (factories) na vytváření objektů destinations a connections.

Vyhledání a zpřístupnění těchto servisních objektů je zajištěno přes JNDI.

Obrázek 8.1. Spolupráce JMS a JNDI (z tutoriálu J2EE Sun)

Spolupráce JMS a JNDI (z tutoriálu J2EE Sun)

JMS - domény

Většina implementací JMS umožňuje:

point-to-point messaging

zasílání zpráv od jednoho odesílatele k jednomu příjemci

publish-subscribe

více odesílatelů může zprávu "vystavit" na místo, kam se odběratel ("předplatitel") může zapsat a zprávy odebírat

Point-to-point Messaging

Proces P-to-P zasílání zpráv zahrnuje tři základní participující objekty:

klient-odesílatel

vytvoří a pošle zprávu do fronty zpráv

fronta zpráv

zprávu přijme a zajistí její "přežítí" než je zkonzumována nebo zastará (time-out)

klient-příjemce

odebírá zprávy z fronty

Vztah producent:konzument je 1:1.

Obrázek 8.2. Mechanizmus Point-to-Point (z tutoriálu J2EE Sun)

Mechanizmus Point-to-Point (z tutoriálu J2EE Sun)

Publish/Subscribe

Producent adresuje zprávu tzv. tématu (topic).

Konzument se může přihlásit k odběru zpráv k tomuto tématu.

Vztah producent:konzument tak není obecně 1:1.

Systém zabezpečí uchování zprávy na tak dlouho, dokud ji všichni odběratelé nepřečtou.

Obrázek 8.3. Mechanizmus Publlish/Subcscribe (z tutoriálu J2EE Sun)

Mechanizmus Publlish/Subcscribe (z tutoriálu J2EE Sun)

Komponenty JMS API

Komponenty (třídy, rozhraní):

  • Administered objects

  • Connections

  • Sessions

  • Message Producers

  • Message Consumers

  • Messages

Obrázek 8.4. Programovací model JMS API (z tutoriálu J2EE Sun)

Programovací model JMS API (z tutoriálu J2EE Sun)

Zpracování zprávy

Klient přijímající zprávu (konzument) ji může přečíst v režimu:

synchronním

řekne si o ni metodou receive

asynchronním

klient je posluchačem události "přijetí zprávy" (metoda onMessage); systém událost vyvolá

takovým typickým klientem je Message-driven Bean (EJB komponenta)

Demo JMS s použitím Sun Java System Message Queue

Použití Sun Java System Message Queue

Sun nabízí podrobný tutoriál k použití jeho implementace systému řízení zasílání zpráv: Sun Java System Message Queue

Součástí tutoriálu je Quick Start Tutorial s praktickým návodem jak nainstalovat, přeložit a spustit server a jednoduchého klienta.

Co je třeba pro překlad klienta

Pro překlad klienta musíme mít v CLASSPATH tyto soubory:

jar soubory (z adresáře IMQ_HOME\lib\)

jms.jar imq.jar jndi.jar (u Javy 1.4 je to automaticky, není třeba přidávat do CLASSPATH)

Spuštění serveru (Message Brokeru)

Provedeme spustitelným souborem z IMQ_HOME/bin/

  • imqbrokerd -tty

Server SJS MQ se rozběhne s hláškami:

Obrázek 8.5. Spuštění SJS Message Queue

Spuštění SJS Message Queue

Test běhu SJSMQ

Zda MQ běží v pořádku lze zjistit dotazem:

  • imqcmd query bkr -u admin -p admin

MQ odpoví:

Obrázek 8.6. Test běhu SJS MQ

Test běhu SJS MQ

Kostra jednoduché aplikace

Demo HelloWorldMessage z adresáře IMQ_HOME/demo/helloworld/helloworldmessage má tyto hlavní prvky (viz tutoriál):

  1. Import the interfaces and Message Queue implementation classes for the JMS API.

    The javax.jms package defines all the JMS interfaces necessary to develop a JMS client.

    import javax.jms.*; 
  2. Instantiate a Message Queue QueueConnectionFactory administered object. A QueueConnectionFactory object encapsulates all the Message Queue-specific configuration properties for creating QueueConnection connections to a Message Queue server.

    QueueConnectionFactory myQConnFactory = 
      new com.sun.messaging.QueueConnectionFactory(); 

    ConnectionFactory administered objects can also be accessed through a JNDI lookup (see Looking Up ConnectionFactory Objects). This approach makes the client code JMS-provider independent and also allows for a centrally administered messaging system.

  3. Create a connection to the message server. A QueueConnection object is the active connection to the message server in the Point-To-Point programming domain.

    QueueConnection myQConn =
      myQConnFactory.createQueueConnection();
    
  4. Create a session within the connection. A QueueSession object is a single-threaded context for producing and consuming messages. It enables clients to create producers and consumers of messages for a queue destination.

    QueueSession myQSess = myQConn.createQueueSession(false,
      Session.AUTO_ACKNOWLEDGE);
    

    The myQSess object created above is non-transacted and automatically acknowledges messages upon consumption by a consumer.

  5. Instantiate a Message Queue queue administered object that corresponds to a queue destination in the message server. Destination administered objects encapsulate provider-specific destination naming syntax and behavior. The code below instantiates a queue administered object for a physical queue destination named “world”.

    Queue myQueue = new.com.sun.messaging.Queue("world"); 
    

    Destination administered objects can also be accessed through a JNDI lookup (see Looking Up Destination Objects). This approach makes the client code JMS-provider independent and also allows for a centrally administered messaging system.

  6. Create a QueueSender message producer. This message producer, associated with myQueue, is used to send messages to the queue destination named “world”.

    QueueSender myQueueSender = myQSess.createSender(myQueue);
     
    
  7. Create and send a message to the queue. You create a TextMessage object using the QueueSession object and populate it with a string representing the data of the message. Then you use the QueueSender object to send the message to the “world” queue destination.

    TextMessage myTextMsg = myQSess.createTextMessage(); 
    myTextMsg.setText("Hello World"); 
    System.out.println(“Sending Message: “ + myTextMsg.getText()); 
    myQueueSender.send(myTextMsg);
    
  8. Create a QueueReceiver message consumer. This message consumer, associated with myQueue, is used to receive messages from the queue destination named “world”.

    QueueReceiver myQueueReceiver = 
      myQSess.createReceiver(myQueue);
    
  9. Start the QueueConnection you created in Step 3. Messages for consumption by a client can only be delivered over a connection that has been started (while messages produced by a client can be delivered to a destination without starting a connection, as in Step 7.

    myQConn.start();
    
  10. Receive a message from the queue. You receive a message from the “world” queue destination using the QueueReceiver object. The code, below, is an example of a synchronous consumption of messages (see Message Consumption: Synchronous and Asynchronous).

    Message msg = myQueueReceiver.receive();
    
  11. Retrieve the contents of the message. Once the message is received successfully, its contents can be retrieved.

    if (msg instanceof TextMessage) {
      TextMessage txtMsg = (TextMessage) msg; 
      System.out.println("Read Message: " + txtMsg.getText()); 
    }
  12. Close the session and connection resources.

    myQSess.close(); 
    myQConn.close();
    

Kapitola 9. Webové služby

Webové služby

Webové služby

Webové služby

Webové služby typu REST

Motivace

"Klasické" webové služby jsou v poslední době kritizovány z několika důvodů:

  • režie služeb je velká

  • flexibilita často zbytečně velká, protokoly mají více vrstev, než je prakticky nutné (SOAP)

  • psaní služeb zahrnuje vytváření řady složitých (XML) popisovačů - nelze psát bez spec. nástrojů

  • nasazení služeb má poměrně velkou vstupní bariéru: vyžaduje aplikační server a speciální klientský SW

  • interoperabilita mezi platformami (a jazyky) není vzhledem ke složitosti standardů stoprocentní

Webové služby typu REST (Representational State Transfer) jsou "lehkou" (lightweight) alternativou k SOAP službám.

Co je REST

REST je tzv. architekturní styl (architectural style), tj. soustava architekturních omezení (architectural constraints), definujích, jak budovat webové služby (aplikace). Není to tedy standard, technologie, nástroj, ani API...

REST vychází z úspěšných postupů používaných na webu od samého počátku.

Autorem REST je Roy Fielding, jenž principy poprvé představil ve své disertaci Architectural Styles and the Design of Network-based Software Architectures. Jeho definice říká: „Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use.

Podrobnější objasnění principů najdeme např. na serveru O'Reilly webservices.xml.com.

Principy

REST je metodika (architekturní styl), jak psát webové služby, či spíše, jak webové služby vystupují vůči klientovi.

REST používá některé pojmy:

zdroj (resource)

typicky odpovídá nějaké (datové) entitě, předmětu zájmu; něčemu, co lze číst, ale obvykle i vytvářet a měnit.

identifikace zdroje

zdroj je identifikován svým URI (např. URL)

reprezentace zdroje

to, co je na požadavek posláno klientovi, tj. např. XML soubor, HTML stránka, obrázek...

Co REST aplikace používají

REST sám o sobě není standardem, REST aplikace jsou ale na standardech přísně založeny - a to na běžných a zavedených jednoduchých standardech:

  • HTTP (přístup ke zdrojům)

  • URL (identifikace zdrojů)

  • XML/HTML/GIF/JPEG/atd. (reprezentace zdrojů)

  • text/xml, text/html, image/gif, image/jpeg, etc (MIME typy zdrojů)

Charakteristika REST služeb

Client-Server

klient "si řekne" o zdroj (princip "pull")

Stateless

(bezestavový) každý klientský dotaz obsahuje veškeré informace potřebné pro vyřízení dotazu na serveru (server neuchovává stav)

Cache

zdroje musejí být označeny, zda podporují kešování

Uniform interface

rozhraní přístupu ke zdrojům (čtení, vytvoření, smazání, modifikace) je jednotné (HTTP GET, PUT, DELETE, POST)

Named resources

zdroje jsou identifikovány pomocí URI (typicky URL)

Interconnected resource representations

reprezentace zdrojů jsou propojeny pomocí URI (URL) a klient tedy může přecházet mezi stavy

Layered components

mezi klienta a server se službou lze umisťovat proxy, keše, brány...

Co rozmyslet před návrhem REST služby

  1. Co jsou URI (tj. zdroje)?

  2. Jaký formát?

  3. Jaké metody každé URI podporuje?

  4. Jaké návratové kódy jsou vraceny?

Postup návrhu

  1. Identifikovat zdroje.

  2. Vytvořit pro ně systém pojmenování (URI).

  3. Určit, jaké metody bude každý zdroj (URI) podporovat (GET, POST, PUT, DELETE?).

  4. Čtení zdroje (GET) nesmí mít vedlejší efekt (nesmí nic modifikovat).

  5. Reprezentace (např. vrácená stránka) by měla umožnit klientovi pokračovat dále, mít odkazy na další zdroje.

  6. Zdroje nemusí (neměly by být) obrovské - lze vždy zpřístupnit jen část a přes odkazy nechat klienta dotaz upřesnit.

  7. Specifikovat schéma pro reprezentaci zdroje (DTD, XML Schema, RelaxNG, Schematron). Rovněž pro vytvoření a modifikace zdroje je dobré schéma zveřejnit.

  8. Popsat službu pomocí WSDL nebo aspoň HTML.