Úvod
Cílem této diplomová práce je ukázat možnosti použití technologie Javy v tvorbě informačního systému. Diplomová práce je rozdělena do čtyř hlavních kapitol. První kapitola je zaměřena na základní seznámení s programovacím jazykem Java. V této části je načrtnuta historie vývoje, vlastnosti jazyka a popis základních prvků specifikace. V této části se předpokládá znalost teorie objektově orientovaného programování a jazyka C++. Cílem kapitoly je získání základní orientace ve zdrojovém kódu jazyka Java. V druhé části je na praktickém příkladu ukázána technologie appletu. Ve třetí části je popsána technologie JDBC, která má velký význam pro tvorbu informačních systémů v centralizovaném i distribuovaném prostředí. Poslední čtvrtá část demonstruje na praktickém příkladu využití všech výše uvedených technologií. Zdrojový kód příkladu je v zhledem k rozsahu uveden na přiložené disketě.
1
Programovací jazyk Java
Java je nový programovací jazyk, jehož základy začaly vznikat v roce 1991. V té době byl ve společnosti Sun Microsystems zahájen projekt „Green“, jehož cílem bylo vytvořit jednoduché operační prostředí pro spotřební elektroniku. Tým odborníků definoval nejzákladnější vlastnosti tohoto segmentu trhu, které později významně ovlivnily specifikaci prostředí (např. nezávislost na architektuře systému). Aby bylo možné dosáhnout daného cíle, bylo nutné vytvořit nový programovací jazyk, protože se ukázalo, že žádný ze současných programovacích jazyků nevyhovuje daným požadavkům. V polovině roku 1991 člen týmu James Gosling začal vyvíjet jazyk OAK. Po několika letech zkušenosti s tímto jazykem a významným přispěním dalších spolupracovníků byl přepracován pro využití v síti Internet a přejmenován na jazyk JAVA. V současné době je Java vyspělým jazykem, připraveným pro široké využití. Přesto se očekává, že během několika následujících let bude vytvořeno několik verzí, které budou zaručovat zpětnou kompatibilitu k již vyvinutým aplikacím. Tyto verze by měli být odlišeny extenzí souborového jména. Java kompilátory a systémy budou současně podporovat několik verzí s kompletní kompatibilitou.
1.1 Vlastnosti Java je objektově orientovaný jazyk, který je syntaxí velice podobný jazyku C++, nicméně architekturou vychází především z objektově orientovaných
jazyků Eiffel, Smalltalk, Objective C a Cedar/Mesa. Do Javy je začleněna např. smalltalkovská architektura MVC. Prvky syntaxe jazyka C byly použity především z důvodu snazšího přechodu na tento programovací jazyk Do Javy byly také začleněny nové vlastnosti, které nejsou v současné době v programovacích jazycích zcela běžné (např. vlákna). Následující část popisuje základní vlastnosti jazyka. Objektově orientovaný
Java je objektově orientovaný jazyk. Mezi základní charakteristiky pojmu „objektově orientovaný“ patří tyto: zapouzdření - interní data objektu jsou chráněna před neoprávněným přístupem jiného objektu polymorfizmus - stejná zpráva může být zaslána různým objektům, přičemž reakce závisí na typu každého objektu dědičnost - definice chování nové třídy je odvozena z již existujících tříd dynamická vazba - objekt může přijít odkudkoliv např. ze sítě. Programátor potřebuje zasílat zprávy objektu, aniž by znal jeho typ v době psaní kódu. Dynamická vazba umožňuje maximální flexibilitu v době běhu programu. Nezávislý na architektuře a přenosný
Nezávislost na architektuře je řešena pomocí vlastního binárního kódu, který je nezávislý na jakékoliv hardwarové architektuře, operačním systému a GUI. Formát tohoto kódu je nezávislý na architektuře. Jestliže je pro danou platformu vytvořen run-time systém, můžou být aplikace napsané v Javě používány bez dodatečných úprav. Robustní
Java kompilátory používají při kompilaci rozsáhlou a přísnou kontrolu syntaktických chyb, s pomocí které může být velké množství chyb odhaleno již při vývoji aplikace. Pro zvýšení robustnosti aplikace má také velký význam paměťový model Javy, který eliminuje možnost přepsání a porušení dat. Distribuovaný
Jelikož je v Javě zahrnuta přímá podpora sítě, splňuje základní předpoklady pro tvorbu distribuovaných aplikací. Interpretovaný
Java aplikace využívají pro svůj běh Java virtual machine (JVM). Pro spuštění aplikace v Javě musí být na daném systému přítomen interpreter, který je schopen interpretovat binární kód Javy pro daný procesor. V současné době jsou virtuální stroje různých výrobců rozšířeny o tzv. just-in-time (JIT) kompilátory, které podstatně zvyšují výkon Java aplikací. JIT je integrovaný přímo ve VM a před spuštěním každé metody nejdříve v reálném čase zkompiluje jejich celý kód do nativního kódu. Dynamický
Jazyk Java byl navržen tak, aby byl co nejvíce schopen přizpůsobit se stále se vyvíjejícímu prostředí. Třídy jsou sestaveny až tehdy, kdy jsou skutečně požadovány a můžou být zavedeny odkudkoliv ze sítě. Každý kód, který má být předán intërpreteru pro spuštění, je nejdříve zkontrolován.
Bezpečný
Java kompilátory a run-time systémy implementují několik úrovní kontroly kódu, mezi které např. patří verifikace bajtového kódu. Následující obrázek zobrazuje průběh kompilace a spuštění kódu.
Průběh kompilace
Průběh spuštění
Zdrojový kód Javy
Java kompilátor
Zavaděč bajtového kódu
zavaděč nezná původ kódu
Verifikátor bajtového kódu
Interpreter Bajtový kód Javy
Generátor kódu Runtime
Hardware
Obrázek I: Průběh kompilace a spuštění kódu
víceprocesní
Vestavěná podpora vláken poskytuje programátorům silný nástroj pro tvorbu interaktivních multimediálních aplikací. Java podporuje vlákna na úrovni jazyka s množinou synchronizačních primitiv. Tato primitiva jsou založena na monitorech a podmínkových proměnných. Java monitory jsou reentrantní.
1.2 Specifikace jazyka V následují části jsou popsány některé významné prvky specifikace jazyka. Popis vychází z předpokladu, že čtenář zná principy objektově orientované technologie a jazyka C++. Cílem kapitoly je získání základního přehledu syntaxe významných prvků jazyka a základní orientace v zdrojovém kódu. Přestože je jazyk Java svou syntaxí velice podobný syntaxi jazyka C, vychází architektura především z jazyku Eiffel, Smalltalk, Objective C a Cedar/Mesa. Do Javy je začleněna např. smalltalkovská architektura MVC. Prvky syntaxe jazyka C byly použity především z důvodu snazšího přechodu na tento programovací jazyk.
1.2.1 Typy a hodnoty Java patří mezi jazyky, které provádějí přísnou kontrolu datových typů všech proměnných a výrazů. Silná typová kontrola pomáhá odhalit chyby již při kompilaci programu. Typy se dělí do dvou kategorií, na primitivní a referenční. Primitivní typy
Primitivní typy mají na rozdíl od jazyka C definovanou přesnou velikost a znaménko. Také výchozí hodnota každé proměnné je přesně definována. Podstatné je, že primitivní typy nejsou objekty. Oproti proměnným referenčních typů nemůžou sdílet svou hodnotu s žádnou jinou proměnnou. Následující tabulka (Tabulka 1) obsahuje seznam typů a jejich atributů.
Typ
Definuje
Výchozí hodnota
Velikost (bit)
boolean
logická hodnota (true nebo false)
false
1
char
znak Unicode
\u0000
16
byte
celé číslo se znaménkem
0
8
short
celé číslo se znaménkem
0
16
int
celé číslo se znaménkem
0
32
long
celé číslo se znaménkem
0
64
float
reálné číslo v jednoduché přesnosti
0,0
32
double
reálné číslo v dvojnásobné přesnosti
0,0
64
Tabulka 1: Primitivní datové typy
Aritmetické typy je možné vzájemně kombinovat, přičemž ke konverzím dochází automaticky. Referenční typy
Mezi referenční typy patří třídy, rozhraní(interface), pole a také speciální typ null. Hodnotou referenčního typu je odkaz na objekt. Objekt je dynamicky vytvořen jako instance třídy nebo jako dynamicky vytvořené pole.
1.2.2 Třídy Java je objektově orientovaný jazyk a pomocí tříd reprezentuje klasický objektově orientovaný model. Třída jako vzor pro vytvoření nového objektu definuje nový referenční typ. Ačkoliv Java používá koncepty objektově orientovaného programování, které jsou v mnoha směrech podobné C++, jsou spíše příbuzné jazykům jako je Smalltalk. Implementace třídy se skládá ze 2 částí: deklarace a těla, a podobně jako ve Smalltalku musí být odvozena z tzv. nadtřídy (též supertřída, předek). Java podporuje jednoduchou dědičnost. Společným předkem všech tříd je třída Object. Pro zajištění některých vlastností je namísto násobné dědičnosti použito tzv. rozhraní.
Deklarace třídy Základní deklarace třídy musí obsahovat pouze klíčové slovo class a jméno třídy. Základní forma deklarace třídy vypadá takto: class JménoTřídy { ... } Jméno třídy podle konvence začíná velkým písmenem. Deklarace třídy může být dál rozšířena o deklaraci nadtřídy, o seynam rozhraní, které třída implementuje, a o modifikátory public, abstract, nebo final. Deklarace nadtřídy
V Javě má každá definovaná třída svoji nadtřídu. Pokud při deklaraci není uvedena, je za nadtřídu automaticky považována základní třída Object. Nadtřídu definujeme v deklaraci klíčovým slovem extends a jejím jménem. Forma deklarace vypadá takto: class JménoTřídy extends JménoNadtřídy { ... } Seznam rozhraní (interface) implementovaných tříd
Definovaná třída může deklarovat několik typů rozhraní, což znamená, že třída zaručuje implementaci třídních protokolů, které tato rozhraní deklarují. Seznam jmen implementovaných rozhraní je uveden klíčovým slovem implements, které následuje seznam jmén oddělených čárkou. Rozšířená forma deklarace vypadá takto: class JménoTřídy extends JménoNadtřídy
implements JménoRozhraní_1 [, ... , JménoRozhraní_N] { ... } Klíčové slovo implements podle definice následuje slovo extends. Modifikátory Public, Abstract a Final
V deklaraci třídy je možné použít některé ze tří modifikátorů. Jméno modifikátoru předchází slovo class. Modifikátor public deklaruje, že danou třídu je možné použít v jiném balíku (package), než v kterém je definována. Implicitně je možné třídu použít pouze v balíku, ve kterém je definována. Modifikátor abstract deklaruje, že daná třída je abstraktní. Abstraktní třída může obsahovat abstraktní metody a nemůže mít vlastní instance. Modifikátor final určuje, že žádná třída nemůže být definována jako podtřída takto definované třídy. Tento modifikátor má význam při návrhu a zabezpečení tříd. Protože se modifikátory abstract a final návzájem vylučují, dojde při kompilaci takto definované třídy k chybě. Takto vypadá souhrnná forma deklarace třídy: [ modifikátory ] class JménoTřídy [ extends JménoNadtřídy ] [ implements JménaRozhranní ] { ... } V hranatých závorkách jsou uvedeny nepovinné položky. Tělo třídy Tělo třídy se skládá ze dvou částí, deklarace proměnných a metod. Deklarace proměnných
Základní deklarace proměnných se skládá pouze z uvedení typu proměnné a jména. Jménem proměnné může být jakýkoliv legální identifikátor, který by měl podle konvence začínat malým písmenem. Deklarace proměnné může být rozšířena o další modifikátory, které určují, které další objekty mohou k proměnné přistupovat, jestli je proměnná třídní, nebo instanční, nebo jestli je konstanta. Deklarace proměnné může vypadat takto: [modifikátorPřístupu] [static] [final] [transient] [volatile] typ jménoProměnné Položky uvedené v hranatých závorkách jsou nepovinné. Položky deklarace proměnné mají následující význam: modifikátorPřístupu - určuje, které další objekty mohou k proměnné přistupovat. Protože je definice přístupu k proměnným a metodám totožná, je tato problematika popsána v části „Modifikátory přístupu k prvkům třídy“. static - určuje, že daná proměnná je třídní. final - určuje, že daná proměnná je konstanta. transient - určuje, že proměnná není součástí trvalého stavu objektu. volatile - určuje, že proměnná se mění asynchroně.
Implementace metod
Implementace metod se skládá ze dvou částí: deklarace a těla. Forma deklarace může vypadat takto: [modifikátorPřístupu]
[static]
[abstract]
[final]
[native]
[synchronized]
návratovýTyp jménoMetody ([seznamParametrů]) [throws seznamVýjimek ]
Položky deklarace metody mají následující význam: modifikátorPřístupu - určuje, které další objekty mohou metodu volat. Protože je definice přístupu k proměnným a metodám totožná, je tato problematika popsána v části „Modifikátory přístupu k prvkům třídy“. static - určuje, že daná metoda je třídní. abstract - určuje, že daná metoda je abstraktní, to znamená; že není v dané třídě implementovaná. final - určuje, že metodu není možné předefinovat. native - určuje, že daná metoda je definována v nativním kódu. synchronized - určuje, že metoda mění kritickou sekci třídy nebo její instance. Synchronizace je v Javě zajištěna pomocí monitoru. návratovýTyp - Java vyžaduje, aby kromě jména metody byl definován také návratový typ. Pokud metoda žádnou hodnotu nevrací, musí být v deklaraci namísto návratového typu uvedeno klíčové slovo void. jménoMetody - může být jakýkoliv legální identifikátor. seznamParametrů - definuje typ a počet argumentů předávaných metodě. SeznamParametrů je seznam čárkou oddělených jmen argumentů a jejich typů. Argumenty jsou předávány hodnotou. Pro argumenty primitvních typů to znamená, že metoda nemůže měnit předávané hodnoty. Pro argumenty referenčních typů to znamená, že metoda nemůže měnit referenci na předávaný objekt, ale může měnit přístupné proměnné objektu. seznamVýjimek - uvádí seznam výjimek, které může metoda „vyhodit“. Java podporuje deklarování metod, které mají stejná jména, ale různé hlavičky. Této technice se říká přetěžování metod.
V těle instančních metod je možné použít speciální proměnnou this, která představuje aktuální objekt, a proměnnou super, která představuje rodičovskou třídu. Modifikátory přístupu k prvkům třídy
Java definuje čtyři modifikátory, kterými ovlivňuje kontrolu přístupu k prvkům třídy. Následující tabulka (Tabulka 2) uvádí seznam modifikátorů spolu s označením tříd, které mají při použití daného modifikátoru k prvku přístup. Modifikátor
třída
podtřída
třídy deklarované ve stejném balíku
private
X
protected
X
X
X
public
X
X
X
package
X
ostatní třídy
X
X
Tabulka 2: Modifikátory přístupu
Pokud před prvkem třídy není použit žádný modifikátor, je implicitně nastaven modifikátor package.
Speciální metody
Mezi speciální metody patří tzv. konstruktory a metoda finalize(). Konstruktor je metoda, která zajišťuje inicializaci instance třídy. Konstruktory mají stejné jméno jako třída a nevracejí žádnou hodnotu. Třída může definovat několik konstruktorů, přesněji řečeno, konstruktor může být přetížen.
Pokud
v deklaraci třídy není uveden konstruktor, je při vytvoření instance použit předdefinovaný konstruktor. Metoda finalize() je metoda, která je provedena vždy před odstraněním objektu z paměti. Hlavička metody musí být deklarována takto:
protected void finalize() throws throwable V této metodě by měli být např. uvolněny systémové prostředky. Třída Object V jazyce Java je hierarchie tříd uspořádána do stromové struktury. Na vrcholu stromu je umístěna třída Object, která definuje základní vlastnosti a chování, jenž musí mít každý objekt. Mezi základní chování objektů např. patří schopnost porovnání objektu s jiným, vrátit znakovou reprezentaci objektu, vrátit třídu objektu atd. Třída Class Instance třídy Class reprezentuje všechny třídy a rozhraní pro běžící Java program.Všechny třídy a rozhraní jsou instancemi třídy Class, z čehož vyplývá, že všechny třídy jsou potomky třídy Object a zároveň jsou instancemi třídy Class (včetně třídy Class). Tato třída nemá žádný přístupný konstruktor. Instance třídy je automaticky vytvořena JVM (Java Virtual Machine) při zavedení třídy.
Objekt Třída je „šablonou“, která definuje vlastnosti a chování objektu. Objekt je vytvořen jako instance třídy. Životní cyklus objektu se skládá z: 1) vytvoření, 2) použití a 3) uvolnění objektu. 1) vytvoření objektu - objekt je vytvořen pomocí operátoru new, za kterým následuje jméno třídy a seznam argumentů uvedený v závorkách. Operátor new alokuje paměť, inicializuje instanční proměnné a vyvolá konstruktor, kterému
předá zadané argumenty. Po vytvoření vrátí referenci na nový objekt. Následující příklad ukazuje možné použití operátoru new. Operátor vytvoří instanci třídy Okno a předá jí zadané parametry. new Okno(0, 0, 10, 10) 2) použití objektu - poté, co je objekt vytvořen, je možné objektu zasílat zprávy a měnit jeho stav. Přístup k prvkům je proveden pomocí tečky. V následujícím příkladě je vytvořena instance třídy Okno, uložena reference na nový objekt a zaslána zpráva zmenVelikost s novými hodnotami šířky a výšky okna. Okno wnd = new Okno(0, 0, 10, 10); wnd.zmenVelikost(20, 20); 3) uvolnění objektu - objekty, které již nejsou používány, není nutné explicitně uvolňovat. Java automaticky detekuje objekty, které
se již nepoužívají.
K uvolňování objektů je použita technologie garbage collector. Před uvolněním objektu z paměti je zavolána ukončovací metoda finalize().
1.2.3 Rozhraní (interface) Rozhraní definuje třídní protokol, který může implementovat jakákoliv třída. Třídní protokol může pouze obsahovat deklaraci hlaviček metod (bez jejich implementace) a konstanty. Rozhraní zajišťuje zapouzdření třídního protokolu bez omezení implementace na jednu větev hierarchie dědičnosti. Pokud třída implementuje rozhraní, musí implementovat těla všech metod, které jsou uvedeny v protokolu rozhraní. Jestliže je třída abstraktní, mohou být implementace metod provedeny v její podtřídě. Třída může implementovat více rozhraní.
Tento
mechanizmus
řeší
podobné
problémy,
které
jsou
řešeny
mnohonásobnou dědičností, avšak bez tak velké režie, která je nutná při podpoře mnohonásobné dědičnosti tříd. Rozhraní především umožňuje: třídám na základě jejich podobnosti v chování sdílet programové rozhraní, aniž by byl mezi nimi definovaný rodičovský vztah. definovat třídní protokol, který je od dané třídy vyžadován. Např. třída, která přestavuje nové vlákno (thread), musí definovat metodu run(), pokud třídu není možné definovat jako podtřídu třídy Thread, která metodu deklaruje, musí implementovat rozhraní
Runnable. Tímto
způsobem odpadá nutnost sdílet společné abstraktní rodičovské třídy nebo rozšiřovat třídní protokol třídy Object. zveřejnit pouze rozhraní třídního protokolu objektu, bez zveřejnění třídy. Těmto třídám se také říká anonymní třídy. Mají například význam při distribuci balíků. Rozhraní je referenční datový typ, a proto může být použito na mnoha místech, kde jsou typy používány (např. při deklaraci proměnných, v seznamu parametrů metody aj.). Rozhraní v Javě vytváří hierarchii, která je nezávislá na hierarchii tříd.
Definice rozhraní
Definice rozhraní se skládá, tak jako u definice třídy, z deklarace hlavičky a implementace těla. Forma deklarace rozhraní vypadá takto: [public] interface JménoRozhraní [extends seznamPředků] {
... } Položky deklarace rozhranní mají následující význam: public - určuje, že rozhranní je možné použít v jakékoliv třídě v jakémkoliv balíku. Pokud toto klíčové slovo není uvedeno, mohou toto rozhraní používat pouze třídy definované v stejném balíku. JménoRozhraní - podle konvence jméno začíná velkým písmenem a většinou je ukončeno koncovkou „able“ nebo „ible“ např. Runnable. extends seznamPředků - seznamPředků je seznam rozhraní, z kterých nově definované rozhraní dědí všechny konstanty a metody. Na rozdíl od tříd však může dědit z několika rozhraní. Tělo rozhraní se skládá z deklarací metod a konstant. Pro prvky rozhraní není možné použít modifikátory transient, volatile, synchronized, private a protected. Pro metody jsou implicitně nastaveny modifikátory public a abstract. Pro konstanty jsou implicitně nastaveny modifikátory public, static a final.
1.2.4 Balíky (Packages) V jazyce Java se knihovnám říká package, v českém překladu je tomuto slovu asi nejblíže slovo balík. Balík obsahuje skupinu rozhraní a tříd a zabezpečuje, aby nedocházelo ke konfliktům jmen. Vytvoření balíku
Pokud má být ze zdrojového souboru vytvořen nový balík, musí být na prvním řádku, který neobsahuje komentář nebo bílý znak, uveden příkaz package se jménem balíku v následující formě:
package jménoBalíku; Import tříd
Pokud jsou ve zdrojovém kódu využívány třídy a rozhraní definované v jiném balíku, musí být nejdříve importované pomocí příkazu import, nebo musí být jméno třídy uvozeno jménem balíku. Jméno balíku a třídy je odděleno tečkou. Syntaxe příkazu import je: import jménoBalíku.jménoTřídy; Namísto jména třídy může být použit znak hvězdičky, který představuje všechny třídy a rozhraní.
1.2.5 Výjimky (Exception) Výjimka je událost, která nastane během provádění programu a poruší normální tok instrukcí. Pokud dojde během provádění metody k chybě, metoda Javy vytvoří exception objekt a předá ho runtime systému. Exception objekt obsahuje informace o výjimce, včetně typu a stavu programu, v kterém došlo k chybě. Runtime systém je zodpovědný za nalezení kódu programu, který výjimku obslouží. V terminologii Javy se vytvoření exception objektu a jeho předání runtime systému říká hození vyjímky (throwing an exception). Po vyvolání výjimky runtime systém hledá kód, který může danou výjimku obsloužit. Systém začne od metody, v které došlo k chybě, postupně prohledávat metody uložené v zásobníku volání metod, dokud nenalezne metodu obsahující obslužný kód tzv. handler výjimky, který může daný typ výjimky obsloužit. Předání výjimky handleru výjimky se říká chycení výjimky (catch the exception). Pokud systém handler výjimky nenalezne, dojde k jeho ukončení spolu s programem.
Java vyžaduje, aby byly odchyceny nebo specifikovány všechny výjimky mimo tzv. runtime výjimky, které vyvolává runtime systém (např. aritmetické výjimky jako je dělení nulou, výjimky související s ukazateli jako je např. přístup k objektu přes null referenci). Specifikace výjimky znamená, že metoda může danou výjimku vyvolat. Specifikace výjimek, kterou může daná metoda vyvolat, se uvádí v deklaraci metody klíčovým slovem throws. Vyvolání a zpracování výjimky
Pro zpracování výjimek se používají příkazy try, catch a finally. Příkaz try uvádí blok kódu, pro který jsou definované handlery ošetřují výjimky. Za tímto blokem následují příkazy catch, které odchytí a zpracují výjimky. Dále volitelně následuje blok finally obsahující kód, který se vždy vykoná. try Forma zápisu vypadá takto: try { příkazy jazyka Java } V bloku jsou uvedeny příkazy, které mohou vyvolat výjimky. catch Mezi blokem try a catch nesmí být uveden žádný kód. Posloupnost zápisu pak vypadá takto: try { ... } catch ( . . . ) { ... } catch ( . . . ) { ...
}... Forma zápisu catch vypadá takto: catch (SomeThrowableObject jménoProměnné) { příkazy jazyka Java } Význam položek: SomeThrowableObject - deklaruje typ výjimky, který daný handler ošetřuje. SomeThrowableObject musí být jméno třídy, která je odvozena od třídy Throwable. jménoProměnné - je jméno, pomocí kterého se handler odkazuje na skutečný objekt výjimky, která byla chycena. finally Blok finally se používá k úklidu po bloku try (např. k uzavření souboru).
1.2.6 Vlákna (Thread) Java podporuje velice mocný prostředek, kterým je možnost vytváření tzv. multivláknových
aplikací. Vlákno má jako sekvenční program svůj začátek,
posloupnost instrukcí a konec.V každém časovém okamžiku je vykonávána pouze jedna operace. Velkou výhodou multivláknových aplikací je, že v jednom okamžiku může být prováděno několik operací. Přímá integrace podpory vláken v programovacím jazyku umožňuje vytvářet robustnější aplikace. Používání vláken je základním programovacím modelem jazyka Java. Podpora vláken zahrnuje synchronizaci založenou na
paradigmatu monitorů a semaforů.
Implementace vychází především ze systému Cader/Mesa společnosti Xerox PARC.
Následující jednoduchý příklad demonstruje nezávislost dvou vláken v procesu. Skládá se ze dvou tříd: Vlakno a TestVlaken. Ve třídě Vlakno, která je podtřídou třídy Thread, jsou definovány dvě metody: Vlakno(...) a run(). První metoda je konstruktorem třídy s jedním argumentem. Jejím úkolem je vyvolat konstruktor nadtřídy a předat jí jméno vlákna. V metodě run() je definováno tělo vlákna, které obsahuje iterační cyklus, v kterém vypíše na standardní výstup iterační číslo, jméno vlákna a poté je uspán. Ve třídě TestVlaken je definována pouze metoda main(String[] args), která vytvoří a spustí dvě vlákna, jimž předá argumentem jejich jméno. class Vlakno extends Thread { public Vlakno(String jmenoVlakna) { super(jmenoVlakna); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int) (Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("KONEC " + getName()); } } class TestVlaken { public static void main (String[] args) { new Vlakno("Prvni vlakno ").start(); new Vlakno("Druhe vlakno").start(); } } Výpis programu demonstruje konkurenční běh obou vláken:
0 Prvni vlakno 0 Druhe vlakno 1 Druhe vlakno 1 Prvni vlakno 2 Druhe vlakno 2 Prvni vlakno 3 Druhe vlakno 3 Prvni vlakno 4 Druhe vlakno 4 Prvni vlakno 5 Druhe vlakno 6 Druhe vlakno 5 Prvni vlakno 7 Druhe vlakno 8 Druhe vlakno 9 Druhe vlakno 6 Prvni vlakno KONEC! Druhe vlakno 7 Prvni vlakno 8 Prvni vlakno 9 Prvni vlakno KONEC! Prvni vlakno Předcházející příklad ukázal jednu ze dvou možností vytváření vláken v jazyce Java, který je založen na dědění od třídy Thread. Druhou možností vytvoření vlákna je definovat třídu, která implementuje rozhraní Runnable. Instanci takto definované třídy je pak možné předat konstruktoru třídy Thread nebo její podtřídě. Tato možnost je využita v případě, pokud je třída podtřídou jiné třídy, než je třída Thread.
2
Applety
WWW jako platformě nezávislá služba je jednou z mnoha oblastí, v které může Java využít výhody své architektury. Java applety jsou programy, pomocí kterých můžou být WWW stránky rozšířeny např. o interaktivní multimediální prvky. Applety můžou tvořit
významný prvek rozsáhlých Internetových
a intranetových informačních systémů. Tato kapitola je především zaměřena na praktickou ukázku tvorby appletu. Na jednoduchém zdrojovém kódu jsou popsány prvky implementace appletu. V první podkapitole je uveden celý zdrojový kód appletu, aby mohl čtenář získat ucelenou představu o struktuře zdrojového kódu. V další části jsou pak popsány prvky kódu. Na závěr kapitoly je popsáno vložení appletu do WWW stránky.
2.1 Applet Hodiny Applet Hodiny je jednoduchý applet, který graficky zobrazuje aktuální čas. Na zdrojovém kódu je pak ukázán postup implementace standardních a některých nadstandardní prvků. Applet např. definuje parametry, kterými lze ovlivnit vzhled, podporuje uvolnění alokovaných zdrojů při přechodu na další stránku, metody getAppletInfo() a getParameterInfo() aj. Na následujícím obrázku (Obrázek 2) je ukázán applet ve WWW prohlížeči. V příkladu 1 je vypsán celý zdrojový kód.
Obrázek II : Applet Hodiny
/* * * * * * */
Hodiny
v1.0
Applet zobrazujici aktualni cas. JavaAPI 1.0.2
import import import import import
java.util.Date; java.applet.Applet; java.awt.Graphics; java.awt.Color; java.awt.Image;
import java.awt.Dimension; import java.net.*; public class Hodiny extends Applet implements Runnable { static final double dCoal = Math.PI / 6; static final double hCoal = Math.PI / 30; double int Date int Color Color Color Image Dimension Graphics Image Thread /** * * @param * @param * @param * @param */
dCoal, hCoal; size = 100; date; h, m, s; bgColor = getBackground(); fingerColor = Color.red; dialColor = Color.blue; bgImage; offDimension; offGraphics; offImage; chClockThread = null;
xS yS r g
x souradnice stredu ciferniku y souradnice stredu ciferniku polomer ciferniku Graphics kontext
protected void drawClock(int xS, int yS, int r, Graphics g){ int double
x1, y1, x2, y2; coal;
date = new Date(System.currentTimeMillis()); h = date.getHours(); m = date.getMinutes(); s = date.getSeconds(); g.setColor(dialColor); if (bgImage != null) { g.drawImage(bgImage, 0, 0, size, size, bgColor, this); } // vykresleni ciferniku for(int i = 0; i < 4; i++) { coal = dCoal * i; x1 = xS + (int) (r * Math.cos(coal)); y1 = yS + (int) (r * Math.sin(coal));
x2 = xS + (int) ((r - size / 10) * Math.cos(coal)); y2 = yS + (int) ((r - size / 10) * Math.sin(coal));
}
g.drawLine(x1, y1, x2, y2); g.drawLine(2 * xS - x1,y1,2 * xS - x2,y2); g.drawLine(x1,2 * yS - y1,x2,2 * yS - y2); g.drawLine(2 * xS - x1, 2 * yS - y1, 2 * xS - x2, 2 * yS - y2);
// mala rucicka g.setColor(fingerColor); x1 = xS + (int) ((r - size / 5) * Math.cos(h * 5 * hCoal + (double) m / 60 * dCoal - Math.PI / 2)); y1 = yS + (int) ((r - size /5) * Math.sin(h * 5 * hCoal + (double) m / 60 * dCoal - Math.PI / 2)); g.drawLine(xS, yS, x1, y1); // velka rucicka x1 = xS + (int) ((r - 2) * Math.cos(m * hCoal - Math.PI / 2)); y1 = yS + (int) ((r - 2) * Math.sin(m * hCoal - Math.PI / 2)); g.drawLine(xS, yS, x1, y1);
}
// sek. rucicka x1 = xS + (int) ((r - 2) * Math.cos(s * hCoal - Math.PI / 2)); y1 = yS + (int) ((r - 2) * Math.sin(s * hCoal - Math.PI / 2)); g.drawLine(xS, yS, x1, y1);
public String getAppletInfo() {
}
return "Applet zobrazujici aktualni cas.\nJavaAPI 1.0.1";
public String[][] getParameterInfo() { String[][] info={ {"size", "int", "velikost appletu"}, {"bgcolor", "int", "barva pozadi v sestnackove soustave (rrggbb)"}, {"fingercolor", "int", "barva hodinovych rucicek v sestnackove soustave (rrggbb)"}, {"dialcolor", "int", "barva ciselniku v sestnackove soustave (rrggbb)"}, {"bgimage", "URL", "URL obrazku na
pozadi"}, }; return info;
}
public void run() { while (Thread.currentThread() == chClockThread)
{
}
}
repaint(); try { chClockThread.sleep(1000); } catch (InterruptedException e){ }
public void init() { String param; int color; param = getParameter("SIZE"); if (param != null) { try { size = Integer.parseInt(param); } catch ( NumberFormatException e ) { } } param = getParameter("BGCOLOR"); if (param != null) { try { color = Integer.parseInt(param, 16); bgColor = new Color(color); } catch ( NumberFormatException e ) { } } setBackground(bgColor); param = getParameter("FINGERCOLOR"); if (param != null) { try { color = Integer.parseInt(param, 16);
}
fingerColor = new Color(color); } catch ( NumberFormatException e ) { }
param = getParameter("DIALCOLOR"); if (param != null) { try {
color = Integer.parseInt(param, 16);
}
dialColor = new Color(color); } catch ( NumberFormatException e ) { }
param = getParameter("BGIMAGE"); if (param != null) { try { URL iurl= new URL(getDocumentBase(), param); bgImage = getImage( iurl ); } catch ( MalformedURLException e ) { } } resize(size, size);
}
public void start() {
} }
if (chClockThread == null) { chClockThread = new Thread(this, "ChClock"); chClockThread.start(); repaint();
public void stop() {
}
chClockThread = null; offImage = null; offGraphics = null;
public void update(Graphics g) { Dimension d = size();
}
if ( (offGraphics == null) || (d.width != offDimension.width) || (d.height != offDimension.height) ) { offDimension = d; offImage = createImage(d.width, d.height); offGraphics = offImage.getGraphics(); } offGraphics.setColor(getBackground()); offGraphics.fillRect(0, 0, d.width, d.height); drawClock(size / 2, size / 2, size / 2, offGraphics); g.drawImage(offImage, 0, 0, this);
public void paint(Graphics g) { }
update(g);
}
Příklad 1 : Zdrojový kód appletu Hodiny Deklarace třídy
Ve zdrojovém kódu appletu musí být hlavní třída definována jako podtřída třídy java.applet.Applet. Třída Applet definuje významnou část chování appletu. Applet musí být např. schopen reagovat na požadavky prohlížeče, mezi které patří požadavek na inicializaci, spuštění, pozastavení, zastavení aj. Toto implicitní chování je samozřejmě možné změnit. Applet Hodiny je multivláknový, a proto je v deklaraci třídy Hodiny uvedeno, kromě nadtřídy Applet, rozhraní Runnable, které třída implementuje. Metody appletu
V podtřídě třídy Appletu musí být definována minimálně jedna z následujících metod: init, start a paint (význam těchto metod je uveden při popisu metod třídy Hodiny). Třída Hodiny definuje následující metody: init() - metoda inicializuje applet vždy při jeho zavedení. Applet Hodiny
při vyvolání této metody převezme parametry zadané v HTML stránce a provede jejich konverzi z typu řetězce na odpovídající typ. Pokud určitý parametr v HTML stránce není uveden, nebo je zadán chybně, bude použita implicitní hodnota.
start() - metoda je vyvolána při spuštění. Applet je spuštěn po zavedení
nebo po návratu na stránku s appletem. V appletu Hodiny je zde vytvořeno a spuštěno vlákno, které zajišťuje aktualizaci hodin každou sekundu. stop() - metoda je vyvolána při opuštění WWW stránky nebo při ukončení
WWW prohlížeče. V appletu Hodiny je zde ukončeno vlákno a uvolněna paměť alokovaná pro buffer ( přesněji řečeno, vlákno a paměť je předána garbage collectoru). paint(Graphics) - toto je jedna ze dvou metod určena pro grafický výstup
appletu. Metoda paint() je používána jako základní výstupní metoda. V appletu Hodiny je použita pouze pro vyvolání metody update(). update(Graphics)- toto je jedna ze dvou metod určena pro grafický výstup
appletu. Metoda update() je používána pro dokonalejší grafický výstup. V appletu Hodiny je v této metodě pomocí techniky dvojitého bufferu odstraněno blikání appletu při překreslování hodin. getAppletInfo() - tato metoda patří k nadstandardním metodám appletu.
Vrací krátký informativní řetězec popisující applet. V současné době není tato metoda podporována žádným WWW prohlížečem. Předpokládá se, že budoucí verze ji již budou podporovat. getParameterInfo()
-
tato metoda patří k nadstandardním metodám
appletu. Je určena pro snazší a korektní zadávání parametrů appletu v HTML stránce. V současné době není metoda podporována žádným WWW prohlížečem. Předpokládá se že budoucí verze prohlížečů poskytnou GUI, pomocí kterého bude možné parametry interaktivně a korektně nastavovat. run() - tuto metodu musí definovat každá třída implementující rozhraní
Runnable. Metoda je srdcem vlákna. V třídě Hodiny tvoří vlákno, které každou sekundu vyvolá požadavek na překreslení appletu a poté se uspí. drawClock(int, int, int, Graphics) - tato metoda vykreslí hodiny s
aktuálním časem na zadaný grafický kontext.
2.2 Vložení appletu do HTML stránky Applet se vkládá do HTML stránky pomocí párové značky <APPLET>. Kompletní syntaxe značky vycházející z JDK verze 1.1 vypadá takto: <APPLET CODEBASE = základníURLAppletu ARCHIVE = seznamArchivů CODE = jménoAppletu ...nebo... OBJECT = serializovanýApplet ALT = alternativníText NAME = jménoInstanceAppletu WIDTH = pixely HEIGHT = pixely ALIGN = zarovnání VSPACE = pixely HSPACE = pixely >
. . . alternativníHTMLKód
Atributy vytištěné tučně jsou povinné. Tato syntaxe je podporována prohlížeči, které implementují Java API 1.1. Protože v současné době většina prohlížečů implementuje Java API 1.0.2, je popis atributů rozdělen podle verze, v které jsou podporovány. Atributy podporované prohlížeči implementující JavaAPI 1.0.2: ALIGN - zarovnání appletu. Možné hodnoty atributu jsou: top, middle, bottom, left, right ALT - atribut specifikující text, který má být zobrazen prohlížečem, který sice podporuje značku <APPLET>, ale nemůže spouštět Java applety. CODE - specifikuje jméno Java appletu. Jméno je bráno jako relativní adresa k URL stránky appletu.
CODEBASE - specifikuje základ URL adresy appletu - adresář obsahující kód appletu. Pokud tento atribut není specifikován, je použita URL adresa dokumentu. HEIGHT a WIDTH - specifikuje výšku a šířku vymezeného prostoru pro applet v pixelech. HSPACE a VSPACE - specifikuje počet pixelů volného prostoru kolem appletu. NAME - specifikuje jméno instance appletu.
...
Značka slouží k předávání parametrů appletu. alternatvníHTMLkód - specifikuje kód, který interpretují pouze prohlížeče, které nepodporují značku <APPLET>. Prohlížeče implementující Java API 1.1 podporují všechny výše uvedené atributy a dále k nim přidává tyto: ARCHIVE - obsahuje seznam jmen archivů, které obsahují třídy a zdroje appletu. Pomocí archivu je možné zavést všechny třídy a zdroje appletu při jednom spojení s WWW serverem. Jelikož archiv může být pakovaný, je celková doba přenosu kratší. OBJECT - specifikuje jméno souboru obsahující serializovanou reprezentaci appletu. Jeden z atributu OBJECT nebo CODE musí být specifikován. ALT - má stejný význam jako v předešlé verzi, pouze je rozšířena množina možných hodnot. Možné hodnoty atributu jsou: left, right, top, texttop, middle, absmiddle, baseline, bottom, absbottom. V příkladě 2 je ukázáno vložení appletu Hodiny WWW stránky. Applet Hodiny definuje tyto parametry:
SIZE - pomocí tohoto parametru je možné určit velikost hodin (appletu). BGCOLOR - tento parametr specifikuje barvu pozadí appletu. Barvy se zadávají v šestnáctkové soustavě ve formátu rrggbb. FINGERCOLOR - parametr specifikuje barvu ručiček DIALCOLOR - parametr specifikuje barvu číselníku. BGIMAGE - parametr specifikuje obrázek, který se má zobrazit na pozadí hodin. Protože applet podporuje metodu getParameterInfo(), je možné popis těchto parametrů získat např. pomocí programu AppletViewer, který je součástí JDK. Při nastavování parametru může uživatel nastavit pouze parametry, které chce změnit. U parametrů, které nemají v HTML kódu nastavenou hodnotu, nebo je nastavena chybně, použije applet implicitní hodnoty. V následujícím příkladu (Příklad 2) je ukázáno vložení appletu Hodiny do WWW stránky a nastavení dvou parametrů: SIZE a BGIMAGE.
Applet Hodiny Příklad 2 : HTML kód vložení appletu Hodiny
2.3 Bezpečnostní opatření Pro uživatele WWW je velice důležité, aby byl jakýkoliv spustitelný kód vložený do WWW stránek bezpečný. Proto jsou Java applety navrženy tak, aby bylo možné jejich činnost kontrolovat. Každý prohlížeč implementuje určitá bezpečnostní opatření, která zajišťují bezpečnost systému. Implementace se v jednotlivých prohlížečích liší. Navržená omezení jsou v současné době velice přísná, a proto se předpokládá, že v budoucnosti budou mít applety více možností. Každý prohlížeč implementuje objekt SecurityMabager, který kontroluje narušení bezpečnosti appletem. Pokud zjistí, že došlo k narušení, vytvoří a vyvolá výjimku SecurityException. Konstruktor objektu SecurityException obvykle vypíše na standardní výstup zprávu. Applet může vyvolanou výjimku chytit a vhodně na událost reagovat. V současné době prohlížeče požadují tato omezení: applet nemůže zavádět knihovny a definovat nativní metody - applet může provádět pouze Java kód. applet obecně nemůže číst, nebo zapisovat soubory na hostitelském počítači applet nemůže vytvářet spojení s jiným počítačem, než z kterého byl zaveden. applet nemůže spustit jakýkoliv program na hostitelském počítači applet nemůže číst určité systémové vlastnosti okna, která vytváří applet, jsou odlišena od oken, která vytváří aplikace - okna jsou např. odlišena varovnou zprávou, barvou nebo obrázkem. Toto omezení pomáhá uživatelům odlišit okna appletů od důvěrných aplikací.
3
JDBC - Java Database Connectivity
Další velice významnou technologií, která rozšiřuje možnosti Java aplikací, a která má velký význam pro budování internetových a intranetových aplikací, je JDBC. Stručně řečeno: JDBC je standardní SQL databázové rozhraní poskytující jednotný přístup aplikací do široké skupiny relačních databází. JDBC je založeno na X/OPEN SQL CLI, podobně jako ODBC.
3.1 Co je to JDBC ? JDBC je nízkoúrovňové Java API pro spouštění SQL příkazů. Skládá se z množiny tříd a rozhraní napsaných v programovacím jazyku Java. S využitím tohoto API je např. možné v informačním systému vytvořit jeden program, který bude přistupovat do všech používaných databází např. Oracle, Informix, Sybase. Není tedy nutné pro každý typ databáze vytvářet zvláštní program. Jelikož je JDBC API rozšířením Java API, je možné např. vytvářet applety, které budou zobrazovat aktuální informace uložené v databázích. JDBC je záměrně vytvořeno jako „call-level“ SQL rozhraní. To znamená, že je zaměřeno na přímé volání SQL příkazů a návrat jejich výsledků. Toto API by mělo jednak sloužit jako základ pro vytváření tzv. higher-level API a současně by mělo najít uplatnění v jeho přímém využití při programování aplikací.
3.2 Srovnání JDBC a ODBC V současné době je ODBC pravděpodobně nejrozšířenější programové rozhraní pro přístup do relačních databází, které nabízí přístup do většiny databází na většině platformách. Pomocí Javy je sice možné toto rozhraní používat přímo, ale mnohem výhodnější řešení je používat ODBC pomocí JDBC-ODBC mostu. Přesto, že je tedy možné využívat v Java aplikacích ODBC, je mnoho důvodů proč používat právě JDBC. Hlavní důvody jsou tyto: přímý přístup k ODBC z Java aplikací není vhodný, protože je používáno C rozhraní. Volání nativního kódu má mnoho stinných stránek zejména v bezpečnosti, automatické přenositelnosti aplikace, robustnosti a implementaci prostý překlad ODBC C API do JAVA API není žádoucí. Java např. nemá pointery a právě ODBC je používá ve velké míře, včetně nechvalně známého pointeru (void *). osvojení ODBC je náročné. ODBC vzájemně kombinuje jednoduché a pokročilé vlastnosti a vyžaduje poměrně složitá nastavení pro jednoduché dotazy. pokud je používáno ODBC rozhraní, musí být na každém počítači ručně nainstalován ODBC manažer a ovladač. Jestliže je však JDBC napsáno pouze v Javě, je kód ze sítě automaticky instalovatelný, přenositelný a bezpečný na všech Java platformách.
3.3 Dvou-úrovňový a tří-úrovňový model JDBC API podporuje pro přístup do databází dvou-úrovňový a tříúrovňový model. Při využití dvou-úrovňového modelu komunikují Java applety a aplikace s databází přímo. Při tomto přístupu je nutné mít pro specifický
databázový systém daný JDBC ovladač. SQL příkazy jsou odeslány do databáze a výsledky příkazů jsou odeslány nazpět. Databáze může být umístěna na jakémkoliv počítači, na který má uživatel přístup prostřednictvím sítě (např. Internetu nebo intranetu). V této konfiguraci client/server tvoří klienta hostitelský počítač a server tvoří počítač, na kterém je umístěna databáze. Tento model zobrazuje obrázek 3.
Java Aplikace
klient
JDBC DBMS protokol DBMS
databázový server
Obrázek III : Dvou-úrovňový model
V tří-úrovňovém modelu jsou příkazy odeslány na střední vrstvu, která odešle SQL příkazy do databáze. Databáze zpracuje SQL příkazy a odešle výsledek zpět na střední vrstvu, která je odešle uživateli. Mezi výhody tohoto modelu patří např. možnost kontroly přístupu k databázím, možnost překladu vyššího API na nízkoúrovňová volání aj. Tento model zobrazuje obrázek 4.
Java applet, HTML prohlížeč
klient HTTP, RMI nebo CORBA volání Aplikační server (Java)
server
JDBC DBMS protokol DBMS
databázový server
Obrázek IV : tří-úrovňový model
3.4 SQL Databázové systémy podporují různé typy SQL syntaxe a sémantiky, které nejsou vzájemně shodné v pokročilých funkcích. JDBC API k tomuto problému přistupuje takto: JDBC dovoluje poslat na DBMS ovladač jakýkoliv řetězec dotazu. Takto může aplikace využít funkčnost, kterou požaduje, s nebezpečím, že může vyvolat chybu na některých DBMS. Ve skutečnosti mohou aplikace používat dotazy, které nejsou SQL, nebo mohou být speciálním deriváty SQL navrženými pro speciální DBMS. JDBC poskytuje ODBC styl escape klauzulí.
Pro
komplexní
aplikace
poskytuje
JDBC
pomocí
rozhraní
DatabaseMetaData informace, popisující dané DBMS. Tak se můžou aplikace přizpůsobit požadavkům a schopnostem určitého DBMS. Protože JDBC API tvoří základ pro vyšší databázové nástroje a API, musí JDBC ovladače zajistit určitou standardní úroveň funkčnosti. Tento problém je řešen pomocí označení „JDBC COMPLIANT“, kterým může být označen pouze ovladač podporující minimálně ANSI SQL-2 Entry Level.
3.5 Přehled hlavních rozhraní JDBC Rozhraní tvoří dvě hlavní skupiny: JDBC API, které je určeno pro aplikační programátory, a nízkoúrovňové ovladače JDBC API.
3.5.1 JDBC API JDBC API je specifická skupina abstraktních Java rozhraní, která dovoluje aplikačním programátorům otevřít spojení s databází, spustit SQL příkazy a zpracovat výsledky. Nejdůležitější rozhraní jsou: java.sql.DriverManager které spravuje zavádění ovladačů a poskytuje podporu pro vytváření nových databázových spojení java.sql.Connection které reprezentuje spojení s konkrétní databází java.sql.Statement které představuje kontejner pro spouštění SQL příkazů na daném spojení. java.sql.ResultSet které kontroluje přístup výsledku.
k řádkům vráceného
Rozhraní
java.sql.Statement
obsahuje
dva
důležité
podtypy:
java.sql.PreparedStatement pro spouštění předkompilovaných SQL příkazů a java.sql.CallableStatement pro spouštění a volání databázových procedur.
3.5.2 Ovladač JDBC Hlavní úlohou databázových ovladačů je poskytnutí implementace abstraktním třídám JDBC API. Přesněji, každý ovladač musí poskytovat implementaci rozhraní java.sql.PreparedStatment, java.sql.CallableStatement, java.sql.Statement, java.sql.Connection a java.sql.ResultSet. Dále každý ovladač potřebuje poskytnout třídu, která implementuje rozhraní java.sql.Driver. Tato třída je důležitá pro určení ovladače ke konkrétní databázové URL.
3.6 Rozdělení ovladačů JDBC V současné době je možné ovladače rozdělit do čtyř kategorií: 1. JDBC-ODBC bridge plus ODBC driver: Most poskytnutý firmou JavaSoft umožňuje přístup přes JDBC prostřednictvím ODBC. Protože musí být kód ODBC zaveden na každém klientském počítači, který používá tento ovladač, je toto řešení vhodné zejména pro uzavřené sítě, v kterých není instalace na straně klienta hlavním problémem, nebo pro aplikační servery v tříúrovňovém modelu. 2. Native-API partly-Java driver: Tento druh ovladačů konvertuje JDBC volání na volání klientského API pro Oracle, Sybase, Informix, DB2 a ostatní DBMS. Toto řešení též vyžaduje, aby byl na straně klienta nainstalován určitý binární kód.
3. JDBC-Net pure Java driver: Tento ovladač překládá JDBC volání do DBMS-nezávislého síťového protokolu, který je poté přeložen serverem do DBMS protokolu. Tento síťový server umožňuje propojit Java klienty s různými databázemi. Použitý protokol závisí na dodavateli. Obecně se dá říct, že toto řešení je nejflexibilnější JDBC alternativou. 4. Native-protocol pure Java driver: Tento ovladač překládá JDBC volání do síťového protokolu používaným DBMS přímo. Toto řešení dovolí přímé volání DBMS serveru z klienta, a proto je to praktické řešení pro Internet. Předpokládá se, že pro přístup k databázím budou především preferovány JDBC ovladače typu 3 a 4. Požití ovladačů 1 a 2 je prozatímní řešení v situacích, v kterých ještě není k dispozici ryzí Java ovladač. Dá se říct, že typ 4 je ideální, třebaže existuje několik situací, v kterých je výhodnější typ 3.
4
Aplikace DBClient
V této části je popsána demonstrační aplikace DBClient využívající JDBC API. Tato aplikace vychází z teoretického příkladu školního informačního systému, který je zaměřen na podporu jednotlivých přednášených předmětů zveřejňováním aktuálních informací např. doplňujících studijních materiálů, nepřítomnosti přednášejícího, konzultačních hodin, termínů zkoušek, konání doprovodných akcí, a dále na dynamickou tvorbu stránek pedagogů. Správa a konfigurace systému je prováděna pouze pomocí WWW a Java appletů. Tím je umožněno využívat tento systém z jakéhokoliv prostředí (např. Unix, Windows, MacOS). Základem systému jsou databáze, z kterých jsou vytvářeny WWW stránky. Přístup k těmto databázím je umožněn pouze registrovaným uživatelům. Aplikace DBClient demonstruje možný přístup klienta k databázi. Jak již bylo výše uvedeno, tento applet je pouze součástí architektury informačního systému. Jeho hlavním cílem je zajistit přístup registrovaným uživatelům k jejich osobním údajům. Tyto údaje jsou uloženy v databázích, z kterých jsou použity pro dynamicky vytvářené stránky.
4.1 Prostředí aplikace Aplikaci tvoří GUI, pomocí kterého je možné interaktivně přistupovat k položkám databáze. Po spuštění se nejdříve zobrazí dialogové okno, v kterém je uživatel požádán o zadání uživatelského jména a hesla. Toto okno je zobrazeno na obrázku 5.
Obrázek V : Dialog pro přihlášení
Po potvrzení a ověření zadaných údajů je zobrazeno hlavní okno, které obsahuje textová pole, umožňující měnit přístupné položky databáze. Toto okno aplikace je zobrazeno na obrázku 7. Textová pole jsou automaticky inicializovány podle jména přihlášeného uživatele.
Obrázek VI : Dialog pro změnu hesla
Aplikaci je možné ovládat pomocí čtyř tlačítek umístěných na pravé straně okna. Význam tlačítek je následující:
tlačítko „Odeslat“ - toto tlačítko slouží k zapsání obsahu textový polí do databáze tlačítko „Obnovit“ - pomocí tohoto tlačítka je možné opětovně zavést položky databáze tlačítko „Zmenit heslo“ - pomocí tohoto tlačítka je možné změnit heslo přihlášeného uživatel. Dialog pro změnu hesla je zobrazen na obrázku 6 tlačítko „Konec“ - ukončí aplikaci.
Obrázek VII : Hlavní okno aplikace
V aplikaci jsou dále využívány informační a dialogová okna, pomocí kterých je uživatel informován o vzniklých událostech.
4.2 Spuštění aplikace Aplikace DBClient je navržena tak, aby ji bylo možné spouštět jako samostatnou aplikaci i jako applet. Tato koncepce byla zvolena proto, aby bylo možné podle aktuálních potřeb využít výhody architektury appletu, nebo samostatné aplikace. To, jakým způsobem bude aplikace použita, závisí na zvoleném spustitelném souboru. Pro spuštění appletu je určen soubor DBClient.class, pro samostatnou aplikaci DBClientGUI.class. DBClient jako applet
Do WWW stránky je pomocí HTML značky <APPLET> vložen applet DBClient.class,
který
podporuje
tyto
tři
parametry:
HOSTNAME,
DATASOURCENAME a BGCOLOR. Pomocí parametru HOSTNAME by měla být specifikována URL adresa serveru IDS Server, který tvoří střední vrstvu v tříúrovňovém modelu. Podrobnější popis tohoto serveru a realizace tří-úrovňového modelu je popsána v následující části. Pokud není tento parametr specifikován, je použita implicitní adresa 127.0.0.0:12. Parametr DATASOURCENAME určuje jméno databázového zdroje. Parametr BGCOLOR nastavuje barvu pozadí appletu. Jestliže nejsou nastaveny parametry HOSTNAME a DATASOURCENAME, jsou při inicializaci appletu vypsány na standardní výstup varovné zprávy, které upozorní uživatele, že tyto parametry nebyly specifikovány, a že proto byly použity implicitní hodnoty. Applet zobrazí na WWW stránce tlačítko, které po kliknutí otevře dialogové okno pro zadání jména a hesla.
DBClient jako samostatná aplikace
Aplikaci je možné spustit v závislosti na prostředí např. z příkazové řádky, nebo kliknutím na příslušnou ikonu. Formát příkazové řádky závisí na operačním
systému. V případě, že je v OS začleněna přímá podpora Java aplikací, jako např. v systému Linux, není nutné z příkazové řádky zavádět JVM (Java Virtual Machine). Podobně jako u appletu i zde se zadává pomocí parametrů URL adresa serveru IDS Server a název databázového zdroje. Takto vypadá formát příkazu v prostředí Windows NT: názevJVM DBClientGUI -url URLAdresa -dsn NázevDatabázovéhoZdroje Popis volitelných položek: názevJVM - příkaz pro zavedení virtuálního počítače, např. java URLAdresa - specifikuje URL adresu serveru IDS Server. NázevDatabázovéhoZdroje - určuje název databázového zdroje. Pokud nejsou specifikovány parametry příkazu, jsou použity implicitní hodnoty. Takto je například možné použít tento příkaz: java DBClientGUI -url 192.168.33.94:12 -dsn InfoSystem
4.3 Přístup k databázím Aplikace používá pro přístup k databázím JDBC ovladač dodávaný se serverem IDS Server. Tak může aplikace využít JDBC API pro přístup k databázím, které jsou napojeny na výše uvedený server. Tento ovladač patří mezi ovladače kategorie 3. IDS Server je internetový server umožňující přístup k databázím. Běží jako samostatný TCP/IP program na určité IP adrese a portu. Pro veškerou komunikaci používá HTTP protokol. Klient se při přístupu k databázím napojuje přímo na tento server. Svou architekturou je vhodný pro centralizovaná i distribuovaná prostředí. V současné době tento server umožňuje přístup ke
všem databázovým systémům, které podporují ODBC na systémech Windows NT a Windows 95. V budoucnosti by měl být přístup rozšířen o nativní podporu systému Oracle, Sybase, SQL server a ostatní hlavní databázové systémy.
4.4 Struktura zdrojového kódu Zdrojový kód je rozdělen do dvou souborů: DBClientGUI.java a DBClient.java. Výpis obou souborů je vytištěn v příloze diplomové práce. Ve zdrojovém kódu jsou definovány tyto třídy: DBClientGUI, DBClient, IDSDatabase, PasswordDlg, ChangePasswordDlg, ShowDialog, MessageDlg Třída DBClientGUI Třída je deklarována takto: class DBClientGUI extends Frame
Hlavním úkolem této třídy je definovat GUI aplikace, a proto je odvozena ze třídy Frame, která představuje zapouzdřené okno aplikace nejvyšší úrovně. Okno, které třída vytváří je zobrazeno na obrázku 7. Třída definuje tyto metody: 1) public DBClientGUI(IDSDatabase) - metoda je konstruktorem třídy. V konstruktoru jsou do okna vloženy komponenty AWT a nastaveny managery prostředí (layout managers). Parametrem této funkce je instance třídy IDSDatabase. 2) public synchronized void show(BigDecimal) - při vyvolání metody je zobrazeno okno a textová pole jsou nastaveny na příslušné hodnoty.
3) public
boolean
handleEvent(Event)
- v této metodě jsou
obslouženy události okna. Konkrétně je zde obsloužena událost zavření okna. 4) public boolean action(Event, Object) - toto je druhá metoda pro obsluhu událostí. Na rozdíl od předcházející metody jsou zde obsluhovány události komponent. V tomto případě vložených tlačítek. 5) public static void main(String args[]) - tato metoda tvoří vstupní bod tzv. standalone aplikace - aplikace, která běží nezávisle na prohlížeči. V metodě je zaveden JDBC ovladač, jsou převzaty parametry z příkazové řádky a zobrazeno dialogové okno pro zadaní uživatelského jména a hesla. Třída DBClient Třída je deklarována takto: public class DBClient extends Applet implements Runnable
Třída tvoří applet, který zobrazí na WWW stránce tlačítko, jehož úkolem je po kliknutí otevřít dialogové okno pro zadání uživatelského jména a hesla. Třída definuje tyto metody: 1) public void init() - metoda převezme parametry z HTML kódu a vloží tlačítko na WWW stránku. 2) public void start() - metoda vytvoří vlákno. Činnost vlákna je popsána při popisu metody run(). 3) public synchronized void run() - metoda tvoří srdce vlákna. Úkolem vlákna je zavést hlavní třídy aplikace ze serveru na stranu klienta ještě před aktivací tlačítka, aby byla celková doba spuštění aplikace minimální. Po zavedení tříd vlákno přejde do stavu čekající.
V tomto stavu setrvá do aktivace tlačítka. Poté vytvoří dialogové okno pro zadání uživatelského jména a hesla. 4) public
synchronized
boolean
action(Event,
Object)
-
v metodě je obsloužena událost kliknutí na tlačítko. Třída IDSDatabase Třída je deklarována takto: class IDSDatabase Tato třída zajišťuje přístup aplikace k databázím. Třída definuje tyto metody: 1) public IDSDatabase(String,
String)
-
v konstruktoru
se
inicializují instanční proměnné. Konstruktoru se předává URL adresa serveru IDS Server a název databázového zdroje. 2) protected void finalize() throws Throwable - tato metoda má podobný význam jako destruktor v jazyce C++. Metoda uzavře spojení s databází, pokud je otevřeno. 3) public String getJDBCURL() - metoda vrátí JDBC URL aktuálního objektu. 4) public void openConnection() throws SQLException - metoda otevře spojení se serverem IDS Server. 5) public
void
closeConnection()-
metoda uzavře spojení se
serverem IDS Server. 6) public boolean passwordOK(String, String) throws SQLException - metoda kontroluje správnost hesla k zadanému uživatelskému
jménu. Uživatelské jméno a heslo je předáno parametry. 7) public
void
changePassword(BigDecimal,
String)
throws
SQLException - metoda změní v databázi heslo zadaného uživatele.
Identifikační číslo uživatele a heslo je zadáno parametry.
8) public BigDecimal getPasswordID(String userName) throws SQLException - metoda vrátí identifikační číslo uživatele k zadanému
uživatelskému jménu. 9) public void setTextFields(DBClientGUI, BigDecimal) throws SQLException - metoda inicializuje obsah textových polí hlavního
okna hodnotami načtenými z databáze. Parametry se předává reference na okno a identifikační číslo uživatele. 10) public
void
updateEmployee(DBClientGUI,
BigDecimal
)
throws SQLException - metoda uloží obsah textových polí hlavního
okna do databáze. Parametry se předává reference na okno a identifikační číslo uživatele. Třída PasswordDlg Třída je deklarována takto: class PasswordDlg extends Dialog
Třída tvoří dialogové okno pro zadání uživatelského jména a hesla. Třída je podtřídou třídy Dialog, která obsahuje zapouzdřené okno dialogového boxu. Třída definuje tyto metody: 1) public PasswordDlg(DBClientGUI, IDSDatabase) - v konstruktoru jsou inicializovány některé instanční proměnné a dále jsou do dialogového okna vloženy komponenty AWT a nastaven manager prostředí (layout manager). Parametry se předává rodičovské okno a instance třídy IDSDatabase. 2) public
boolean
action(Event,
události tlačítek v dialogovém okně. Třída ChangePasswordDlg Třída je deklarována takto:
Object) - metoda obsluhuje
class ChangePasswordDlg extends Dialog
Třída tvoří dialogové okno pro změnu hesla. Toto okno je zobrazeno na obrázku 6. Třída definuje tyto metody: 1) public ChangePasswordDlg(DBClientGUI, IDSDatabase, BigDecimal)
- v konstruktoru jsou inicializovány některé instanční
proměnné a dále jsou do dialogového okna vloženy komponenty AWT a nastaven manager prostředí (layout manager). Parametry se předává rodičovské okno, instance třídy IDSDatabase a identifikační číslo uživatele. 2) public boolean action(Event, Object) - metoda obsluhuje události tlačítek v dialogovém okně. 3) public
boolean
handleEvent(Event)
- v této metodě jsou
obslouženy události dialogového okna. Konkrétně je zde obsloužena událost zavření okna. Třída ShowMessage Třída je deklarována takto: class ShowMessage extends Dialog
Třída tvoří informační okno. Třída definuje tyto metody: 1) public ShowMessage(String, Frame) - v konstruktoru je vytvořeno dialogové okno s komponentou typu Label, které je inicializováno předaným řetězcem. Parametry se předává zpráva a rodičovské okno.
2) public
boolean
handleEvent(Event)
- v této metodě jsou
obslouženy události dialogového okna. Konkrétně je zde obsloužena událost zavření okna. Třída MessageDlg Třída je deklarována takto: class MessageDlg extends Dialog
Třída tvoří informační dialogové okno. Třída definuje tyto metody: 1) public MessageDlg(String, Frame) - v konstruktoru je vytvořeno dialogové okno s komponentou typu Label a tlačítkem. Label je inicializován řetězcem, který je předán parametrem. Dále je předáno rodičovské okno. 2) public boolean action(Event, Object) - metoda obsluhuje události tlačítka. 3) public
boolean
handleEvent(Event)
- v této metodě jsou
obslouženy události dialogového okna. Konkrétně je zde obsloužena událost zavření okna.
Závěr
Java je významná nová technologie, která umožňuje vytváření nových typů aplikací. Přímá podpora vláken, sítě a databází dovoluje vytvářet robustní distribuované aplikace, které mohou tvořit základ informačních systému. Nezávislost těchto aplikací na jakékoliv platformě snižuje celkové náklady na budování informačního systému a umožňuje podle aktuálních požadavků jednoduchý přechod na novou hardwarovou základnu. Přestože je Java v současné době vyspělý programovací jazyk, je stále rozšiřována o nové technologie.
Seznam použité literatury: James Gosling, Bill Joy and Guy Steele: The Java Language Specification Mary Campione and Kathy Walrath: The Java Tutorial:Object-Oriented Programming for the Internet David Flanagan: Programování v jazyce Java James Gosling and Henry McGilton: The Java Language Environment: A White Paper Graham Hamilton and Rick Cattel: JDBC: A Java SQL API JDK 1.1 Documentation, Sun Microsystems Java, nový objektový jazyk, Softwarové noviny, 1/1997 Jak rychle vám poběží Java, PC Magazine, 11/1996