A Web gyors átalakuláson ment keresztül,
egyszerű közlési eszközből kifinomult alkalmazási környezetté vált.
A Web tartalmának egyre nagyobb része statikus HTML fájlok hleyett
dinamikusan generált lapokba került, melyek egyszeri megjelenés után
eltűnnek. Sokan a webhelyek közül, különösen a nagyobb kiskereskedelmi
helyek, melyeknek állandóan változó raktárakkal és árakkal kell dolgozniuk,
teljes egészében dinamikusan generált lapokból állnak, egyetlen HTML fájlt
sem tartalmaznak. A dinamikusan generált tartalomnak sok előnye
van: elmarad a HTML fájlok verzióellenőrzése, a lapok jobban elviselik a
változó környezetet, a tartalmat minden olvasónál testre lehet szabni. Van
azonban egy hátrány. A dinamikusan generált webhelyek sokkal több kifinomult
programzási munkát kívánnak a tartalmuk megalkotásánál és átadásánál. Az új
Java Servlet API és a Web szerverek
segítséget nyújtnak azáltal, hogy
könnyen kezelhető, nagyteljesítmlnyű, rugalmas Java
platformot adnak a weblapok röptében való összeállításához. |
A java platform végfelhasználói alkalmazásokban és elosztott alkalmazások kliens oldalán tapasztalt népszerűségének több oka van. A java nyelv a fáradságosabb programozói feladatok közül, mint például a memóriakezelés, sokat automatikusan elvégez. Hagyja a programozót, hogy a tényleges alkalmazásra összpontosítson, a jelentéktelen nyelvi részletkérdések helyett. A java alaposztályok sok hasznos adatmanipulációs és tárolási osztályt foglalnak magukba, amelyek még kevesebb alkalmazástól független kódot kívánnak meg a programozótól. Végül az írd meg egyszer, futtasd bárhol zárja le a minden lehetséges klienst támogatni akaró átültetési erőfeszítések sorát. A szerveroldali alkalmazásfejlesztők is részesülnek ezekben az
előnyökben. Ezenkívül, mivel a szerveroldali programozóknak gyakran kell
foglalkozniuk a fájlrendszerek és operációs rendszer-specifikus struktúrák
részleteivel, mint például konfigurációs fájlok és portszámok, a java
platformon szerveroldali alkalmazások egy kis odafigyeléssel és
előrelátással szintén bárhol futtathatóra írhatók. A közbenső réteg alkatelemei gyakran
éppen olyan platformfüggetlenné tehetők, mint a kliensoldali appletek. |
A
java szervletek |
A szervletek Java nyelven készült olyan szerveroldali
szoftverkomponensek, amelyek Java-futtató rendszerrel elátott HTTP
szerverekbe beágyazva kliensek részére különféle szolgáltatásokat
nyújthatnak.[4] Tehát a szervlet
valójában egy speciális Java program, amely egy webszerverrel szorosan
együttműködve a szerveroldalon lehetővé teszi HTML oldalak
dinamikus létrehozását és paraméterezését különböző átviteli (például
HTTP) protokollon keresztül.[5] Mivel ezek a programok a szerver oldalán
működnek, ezért a kliensek felé nyújtott szolgáltatásuknak nem része a
felhasználói felület biztosítása.[4] Pontosabban a webszerver
funkcionalitását lehet velük kibővíteni, mert ha egy kliens olyan HTML
oldalt kér a webszervertől, melyet egy szervlet állít elő, akkor a
webszerver tulajdonképp csak delegálja a kérést a szervlet felé, majd a
szervlet által generált oldalt továbbítja a kliensnek. [5] Bár a szervletek Java nyelven készülnek, a
szolgáltatásaikat természetesen bármilyen operációs rendszeren
működő, bármilyen programozási nyelven elkészített programokból igénybe
lehet venni. A lényeg az, hogy a
szolgáltatásokat igénybe venni szándékozó alkalmazás valahogyan képes legyen
a hálózaton keresztül történő kommunikációra. Természetesen a szervletek
nemcsak szerver szerepköröket tölthetnek be, például az említett három
résztvevős kliens-szerver struktúrában a szervletek a középső,
alkalmazásfüggő szerver komponensek szerepét is betölthetik úgy, hogy
közben maguk is kliensei valamely háttéradatbázis elérését biztosító
szervernek. A szervletek sokféle célra használhatók. A tipikus
felhasználási céljaik között említést érdemel a HTML-űrlapok
feldolgozása és a háttérben lévő JDBC programozói felülettel
elérhető adatbázisok karbantartása az űrlapok tartalma alapján.
Ezenkívül a szervletek jól felhasználhatók több résztvevő szinkronizált
kommunikációjának megszervezésére is olyan alkalmazásstruktúrában, ahol egy
több kliens párhuzamos kiszolgálását végző szervlet alkalmazás az összes
rákapcsolódott kliens szinkronizált kommunikációjának megvalósításában
segíthet. A szervletek képesek a kliens alkalmazások kéréseinek más
szerveroldali komponensekhez történő továbbítására, így a szervletek
részt vehetnek középső, alkalmazásfüggő szerver komponensként a
háttérben levő szerverek terheléskiegyenlítését segítő stratégiák
megvalósításában. |
A webszerver és
a szervlet közti kommunikáció a
szervlet API-n keresztül történik. Szervleteket tehát csakis olyan
webszerverekkel lehet használni, melyek támogatják ezen API-t, és
természetesen képesek Java programok futtatására. A servlet API nem része a
standard JDK-nak, de letölthető hozzá különálló fejlesztőkörnyezet
(JSDK- Java Servlet Development Kit). A fejlsztőkörnyezet tartalmazza a
szervlet API implementációját, HTML dokumentációját, néhány példaprogramot, valamint
egy egyszerű Java alapú webszervert, melynek segítségével akkor is
kipróbálhatjuk szervleteinket, ha nincs a gépünkön más webszerver telepítve. |
A szervlet API implementációját a servlet.jar fájl
tartalmazza. Szervlet fordításakor ezen fájlnak elérhetőnek kell lennie
az osztályelérési útvonalon keresztül. A lefordított szervlet bájtkódját a
webszerver előre megadott alkönyvtárába kell másolni. Ennek pontos
elhelyezkedése a webszerver konfigurációjától függ, de rendszerint egy servlets
nevű alkönyvtárat szoktak használni erre a célra. |
Mivel
egy szervlet csak egy webszerverrel együtt képes működni, ezért a
szervlet futtatása a webszerver feladata. Erre akkor kerül sor, ha a
webszerver olyan kérést kapott, melyet a szervletnek kell feldolgoznia. Ez
rendszerint a kért url alapján könnyen megállapítható, mert az a szervleteket
tartalmazó útvonalat (általában /servlet), valamint a futtatandó szervlet
nevét tartalmazza. Ilyenkor a kért szervlet szolgálja ki a kliens kérését, a
webszerver pedig a szervlet válaszát adja vissza html oldalként. Tehát a
kliensoldal legfeljebb a kért url alapján jöhet rá, hogy egy szervlettől
kapott választ, mivel a kliens szemszögéből semmi más különbség nincs
egy statikus html oldal, illetve egy szervletet megadó url lehívása között. |
A világháló első legnagyobb újításainak egyike a common gateaway interface (cgi) volt. A cgi előtt a web statikus kőzeg volt, az információt mozdulatlan szövegoldalak, és képek formájában továbbította. A cgi a webmestereket képessé tette arra, hogy dinamikusan generálják a html lapokat. Nemcsak a web tartalmát lehetett a felhasználó igényeire szabni, a felhasználó vissza is küldhetett információt a http szervernek. Ez a kétirányú adatforgalom a web-et egyszerű publikációs eszközből az elektronikus kereskedelem, intranet alkalmazások és más tranzakciós eszközök felületévé tette. A.)Teljesítmény A szervletek használata 30-szor gyorsabb
lehet, mint a cgi. A szervletek nyitott java api-t képviselnek és sok http szerver
támogatja őket. Ez kiterjeszti az alapvető írd meg egyszer, futtasd
bárhol elvet a web backend oldalára is. Gyakorlatilag
egy szervlet nagyon hasonló módon működik, mint egy cgi lapgenerátor. A
szervlet egy java osztály, mely egy webszerverbe töltődik és, a hoszt
webszerveréhez intézett http kérésre felhasználva helyi adatokat, a kérést
adó böngésző által átadott paramétereket és egyéb erőforrásokat,
html lapot vagy más felismerhető típusú választ készít és visszaadja ezt
a szervernek. Mivel a szervlet ugyanabban a processzben és címtérben fut,
mint az ő hoszt webszervere, nagyon kicsi a szervlethívással kapcsolatos
processzek közti adminisztrációs munka (overhead). A http szerver
egyszerűen egy külön szálban meghívja a szervletet és továbbítja az eredményeket
a kérést adó webböngészőnek. Ez sokkal gyorsabb, mint a tipikus cgi
fork/exec/takarítás műveletsor. B.) Egyszerű
használat A
szervleteknél a paramétereket a szervletnek előre elemzett
hash-táblákban adják át. E hash-táblák segítségével könnyű a hozzáférés
a felhasználói adatokhoz. C.) Biztonság Mivel a szervleteket a belső szerkezeténél fogva biztonságosabb
java nyelven írják, sokkal kevesbé valószínű, hogy a http helyi
biztonsága elleni támadások sikerülnek. Olyan webszerverek, melyek szervleteket
és java 2-t implementálnak, védelmi tartományokat használhatnak alkalmazástól
függő biztonsági intézkedések implementálásához. |
A szervletet egy olyan szerverre kell
felinstallálni, amelyik kommunikálni tud a szervletekkel. Általában három forrásból tölthetők fel: ·
classpath-ból ·
a servlets könyvtárból ·
egy URL-ről |
A
szervlet tartós telepítése két dolgot követel meg: a szervlet betöltését
amikor a webszervert indítjuk, csökkentve a várakozási időt, és a
szervlethez egy álnév rendelését. Ez lehetővé teszi, hogy második nevet
adjunk a szervletnek, lehetőleg egy .html kiterjesztéssel ellátott
nevet. Ez elrejti a tényt, hogy egy
url egy szabályos html lap helyett egy szervletre mutat. Ennél fontosabb,
hogy el tudjuk rejteni a szervletet implementáló osztályok nevét. Ha egy bizonyos idő után kicserélnénk
az implementáló osztályt az összes kereszthivatkozások és könyvjelzők
aktualizálása gondot okozna, amit a legtöbben szeretnénk elkerülni. Az
implementációs osztályokat egy álnév mögé rejtve kitérhetünk e probléma
elől. |
A dinamikus lapgenerálás egyik legáltalánosabb felhasználása a HTML formákból kapott input adatok feldolgozása. Ilyenkor szövegmezőkből, legörgethető menükből és egyéb GUI elemekből álló egyszerű formákat használunk a felhasználótól kapott adatok begyűjtésére. Ezek az adatok ezután egy HTTP GET vagy POST kérésben vonódnak össze, amely a webszerveren a megfelelő programot meghívja. A program ezt az inputot az adatbázis lekérdezések, fájl-pásztázások, árumegrendelések kialakítására, vagy más tevékenységekre használja. A program visszaadja a kért adatokat vagy annak megerősítését, hogy a megrendelés egy HTML lapra került. A szervlet API
ezt a fajta felhasználói interakciót azzal könnyíti meg, hogy egyszerű
mechanizmust ad HTML formákból kapott input vételére és elemzésére. |
A Java szervletek szerkezete |
A javax.servlet csomag tartalmazza az összes
szervletspecifikus osztályt és interfészt. Minden szervlet vagy a
javax.servlet.GenericServlet leszármazottja vagy maga implementálja a
javax.servlet.Servlet interfészt, amely az általános szervlet életciklus
metódusokat specifikálja.[5] Ez az
interfész nevezi meg azokat a metódusokat, amelyeket minden szervletnek meg
kell valósítania. A Java szervletek működése: fogadják a
kliensektől származó kéréseket, elvégzik a kliensek által kívánt
szolgáltatásokat, és a kliensnek különféle adatokat küldenek vissza. Nem
szabványos bementről kapják a kliensek kéréseiből származó
adatokat, illetve nem a szabványos kimenetükre írják a válaszukat. A szervlet
szolgáltatását megvalósító metódus a paraméterében kapott adatok alapján tud
egy-egy bemeneti, illetve kimeneti Java I/O csatornát létrehozni, amin
keresztül a klienstől érkezett adatokhoz hozzájuthat, illetve amin
keresztül a kliensének válaszolhat. public interface Servlet{ public void init(ServletConfig config) throws ServletException; public ServletConfig getServletConfig(); public void service(ServletRequest kérés,
ServletResponse válasz) throws ServletException, IOException; public String getServletInfo(); public void destroy(); } A
javax.servlet.Servlet interfész egy szervlet
életének legfontosabb metódusait definiálja. A szervlet életciklusa alatt a
következő három eseményt értjük: ·
szervlet példányosítása ·
szervlet kiszolgál egy kliens kérést
·
szervlet megszüntetése. Ezen
eseményekhez tartozó metódusokat a szervlet interfész specifikálja és a
webszerver hívja meg. a.) Init metódus Az init() metódust a servletet betöltő szerver
hívja meg a szervletet implementáló osztály példányosításakor. Erre
vonatkozóan talán a legfontosabb tudnivaló, hogy amíg ez a metódus nem fut
le, addig a szervlet szolgáltatásait implementáló service() metódus nem kerül
végrehajtásra. Az init() metódus
paraméterében egy javax.servlet.ServletConfig interfészt implementáló
objektumot kap, ami információkat tartalmaz egy szervlet futási
környezetéről. Ezzel lehetőség nyílik önálló szervlet példányok
létrehozására ugyanannak a szervlet osztálynak más kezdeti paraméterezésével
(a különbözőképpen felparaméterezett szervletek a klienseik felé
különböző szolgáltatásokat is nyújthatnak). Az init() metódusnak a
paraméterében kapott objektumot el kell tárolnia, és szükség esetén az
objektum getServletConfig() metódusának meghívásakor az eltárolt
objektumpéldányt a hívónak vissza kell adnia. A paraméterek a ServletConfig
objektum getInitParameter metódusa által hozzáférhetők. A
getParameterValues-hez hasonlóan a getInitParameters egy String-et kap
paraméterként, mely a kívánt paraméter nevét tartalmazza. Eltérően a
getParameterValues-től, a getInitParameters egy String-et ad vissza
String-tömb helyett. Ennek oka az, hogy egy init paraméternek csak egy értéke
van: egy String érték. Amennyiben az
init() metódus nem tudta a kívánt szervletet inicializálni (mert például az
elinduláshoz szükséges adatokat tároló valamelyik adatbázis szerver nem
elérhető), akkor egy javax.servlet.UnavailableException kivételt kell
generálnia, ez a kivétel kellő információt nyújthat a szervletet
indítani szándékozó szerverprogramnak a hiba jellegéről, illetve arról,
hogy érdemes-e a szervlet elindítását újból megpróbálni. b.) Szervlet
beanek A szervlet
beaneknek két nagy előnye van az init tulajdonságokkal szemben. Az egyik
az, hogy míg az init tulajdonságok csak a szervlet inicializálása alatt
állíthatóak be, a bean tulajdonságok bármikor. Eszerint a bean tulajdonságai
röptében, futás közben módosíthatóak. Nem kell kiűríteni és újra
betölteni a szervletet, vagy a webszervert újraindítani ahhoz, hogy a
tulajdonságokat újraolvassa. A másik nagy előny az, hogy az összes Java
Beanhez hasonlóan a szervlet beanek önleírók c.) A service() metódus A szervletek fontosabb metódusaihoz tartozik a
service() metódus. Egy szervlet service() metódusa implementálja a kliensek
felé nyújtott szolgáltatást, ennek a metódusnak a feladata egy kliens
kiszolgálása. Egy szervlet service() metódusának hívásai nem lesznek
szinkronizálva, így ha egyszerre több kliens is igénybe kívánja venni egy
szervlet szolgáltatását, akkor az illető szervlet service() metódusa
egyidejűleg több egymástól független végrehajtási szálon is aktív lehet.
Ilyenkor a végrehajtási szálak közösen használt erőforrásaihoz való
hozzáférés szinkronizációjáról a szervlet készítőjének kell
gondoskodnia. A service() metódus első paraméterében megkap egy
javax.servlet.ServletRequest interfészt implementáló objektumot, ami a kliens
kéréséről tárol információkat, a második paraméterében kapott
javax.servlet.ServletResponse interfészt implementáló objektum segítségével
pedig a kliensnek küldhetők vissza a válaszadatok. A szervlet a szokásos static módosítóval
ellátott osztályváltozóiban tárolhat például állapot információkat a
párhuzamosan (vagy egymás után) kiszolgált kliensekkel felépített
kapcsolatairól, így szükség esetén az egyes kliens/szerver kapcsolatok egymás
közti adatcseréje ezúton megoldható. d.) A destroy() metódus A destroy()
metódust a szervlet futtató környezete akkor hívja meg, ha a szervlet
szolgáltatásaira a közeljövőben várhatóan nem lesz szükség. A szervlet
futtató környezete ezt a metódust meghívhatja például olyankor, ha az
illető szervlet szolgáltatásait már régóta nem vették igénybe, de akkor
is, ha a rendszergazda erre utasította. Amíg egy szervletpéldány klienseket szolgál
ki, addig ez a metódusa nem lesz meghívva. Egy kliens kiszolgálása e
tekintetben a service() metódus futásának idejéig tart, így ha e metódus úgy
működik, hogy egy új önálló programszálat indít a kliens kiszolgálására,
és a metódus még azelőtt visszaér, mielőtt ez az elindított
programszál befejezné a tevékenységét, akkor a szervletet készítő
programozónak kell gondoskodnia az illető programszálak megfelelő
befejezéséről. A destroy() metódus feladatai közé tartozik a szervlet
által a futása során lefoglalt erőforrások felszabadítása, illetve a
szervlet későbbi újraindításához esetleg szükséges adatok kimentése. |
Az előzőekben már láthattuk a
szervletek init() metódusát, annak szerepét. Említettük, hogy a paramétere
információkat tartalmaz a szervlet futási környezetéről. Ez a
gyakorlatban azt jelenti, hogy a szervlet programot futtató szerver különféle
úgynevezett paraméterváltozókon keresztül közli a szervlettel a
munkakörnyezetének fontosabb jellemzőit. a.) Szervletparaméterek: Szervletparamétereket a szervletek
konfigurálására, illetve inicializálására lehet felhasználni. A paraméterek
megadási formája paraméternév= paraméterérték alakú. A paraméterfáljt a webszerver általában csak az
indításkor, egyszer olvassa be, ezért az esetleges változtatások csak a
webszerver újraindításakor lépnek életbe. Jelenleg két szervletparamétert használ a futtató
környezet: ·
Szervlet neve: servletnév.code=servlet osztályának teljes neve – ennek
beállítása után a megadott névvel lehet hivatkozni a szervletre. Ezen név a
webszerverhez küldött URL-ben, illetve további szervletparaméterek
megadásakor is használható. Ha nem adunk meg nevet egy szervlethez, akkor
alapértelmezés szerint annak neve meg fog egyezni a szervlet osztályának
nevével. ·
Szervlet inicializációs paraméterei: servletnév.initArgs=paraméterek – az
így megadott paramétereket a szervlet megkapja az inicializálásakor. A szervlet inicializálásakor kapott ServletConfig
paraméteren keresztül a szervlet inicializációs paramétereit (getInitParameter
és getInitParemeterNames metódusokkal), valamint a szervletet futtató
környezetet reprezentáló ServletContext (getServletContext metódussal)
objektumot lehet lekérdezni. Mivel a GenericServlet automatikusan kezeli a
ServletConfig objektumot, ezért ezen három metódus magára a szervletre is
meghívható. public interface ServletConfig{ public ServletContext getServletContext(); public String getInitParameter(String
paraméternév); public Enumeration getInitParameterNames(); } A getInitParameterNames() metódus visszaadja azoknak a
paramétereknek a nevét, amelyekhez a futtató környezet rendelt valamilyen
értéket, a visszaadott neveken a java.util.Enumeration interfész metódusaival
mehetünk sorba. Egy adott nevű paraméter értékét a getInitParameter()
metódussal kérdezhetjük le, a metódus az egyetlen paraméterében megkapott
nevű paraméter értékét adja vissza. [4] A getParameterValues egy String-ben megkapja a
paraméter nevét és visszaad egy String-tömböt, amely e paraméter
értékeinek halmaza. Ez azt jelenti,
hogy a paramétert még akkor is egy tömbből kell kivennünk, ha teljesen
biztosak vagyunk benne, hogy csak egyetlen értéke lehet. Ez azért kell, mert egyes HTML formaelemek úgy
működnek, hogy egy paraméternévhez több értéket rendelnek hozzá. A
getParameterValues metódus egyszerűen csomóba köti a paraméternévhez
rendelt összes felvehető értéket és egy String tömbben adja vissza
őket. Ez egyszerűbbé teszi az API-t, megengedvén egy metódusnak,
hogy mind egyértékű, mind többértékű paramétereket kezelhessen.
Ezen kívül a paramétereket kissé öndokumentálóbbá is teszi azáltal, hogy nem
kell egy Reflection API-t definiálni, hogy megtudjuk a paraméter származási
helyét és a lehetséges értékeinek számát. Ez a képesség a getParameterNames
metódussal kapcsolatosan arra használható, hogy a szervletünk olyan
paramétereket is felderítsen, amelyeket a kérésben nem várhatott. Arra mindig van esély, hogy a felhasználó üresen hagy
egy mezőt. Ilyenkor ellenőrízni kell, hogy a paraméter neve
létezik-e, és van-e érvényes paraméterérték. Ez úgy történik, hogy a
getParameterValues által String-tömbben visszaadott értékeket
ellenőrizzük. Tipikusan üres mezőre utal, ha nincs tömb vagy az
első String nulla hosszúságú.
[3] A getServletContext() metódussal egy szervlet objektum
hozzáférhet a futtató környezete által nyújtott néhány hasznos
szolgáltatáshoz. A metódus által visszaadott objektum a
javax.servlet.ServletContext interfészt implementálja. Ez az interfész olyan
metódusokat tartalmaz, amelyekkel a rendszerben inicializált többi
szervletről kapunk információkat, valamint ezek segítségével
lehetőség van események naplózására is. public interface
ServletContext{ public Servlet getServlet (String nev) throws
ServletException; public Enumeration getServlets(); public void log
(String uzenet); public String getRealPath (String utvonal); public String getMimeType (String fajlnev); public String getServerInfo(); public Object getAttribute (String attributumnev); } A
getServlet() metódus segítségével
megkaphatjuk a paraméterében megadott nevű szervlet objektum Java
objektumreferenciáját. Ha a megnevezett szervlet (még) nincs a rendszerben,
akkor ez a metódus null értékkel tér vissza. A metódus
javax.servlet.ServletException kivételt vált ki, ha a megnevezett szervletet
nem lehetett a betöltési kísérlet során inicializálni. A getServlets()
metódus visszaad egy java.util. Enumeration interfészt implementáló
objektumot, amely az összes elérhető szervlet referenciáját tartalmazza. A log()
metódussal írhatunk egy üzenetet a szervlet eseménynaplójába. A getRealPath() metódus visszaadja a paraméterében megadott virtuális
szerverelérési útvonalnak megfelelő valódi elérési útvonalat a
megfelelő álneveknek a virtuális elérési útvonalra történő
alkalmazásával, vagy null értékkel tér vissza, ha a virtuális útvonalakat a
szerver nem támogatja, vagy a virtuálisról valódi elérési útvonalra konverzió
valamilyen oknál fogva nem sikerült. A getMimeType() metódus a paraméterében megadott nevú fájl
MIME-típusát adja vissza, ha azt a fájl nevéből vagy tartalmából ki
tudja következtetni. Ha nem tudta ezt kikövetkeztetni akkor null értékkel tér
vissza. A getServerInfo() metódussal a szervletet futtató szerverről
kaphatunk vissza információkat. A getAttribute() metódussal a szerverről további információkhoz is
hozzáférhetünk, amelyekhez az eddig bemutatott metódusokkal nem lehetett
hozzáférni. A szervlet
inicializálásakor érdemes a szervlet teljes futási ideje alatt használt
mezőket beállítani, például adatbázis-kezelő szervlet esetén itt
érdemes megnyitni az adatbázsikapcsolatot. |
Miután a webszerver inicializálta a szervlet egy
példányát, az képesé válik a kliens kérések kiszolgálására. Ha a webszerver
megállapította, hogy egy kérés egy szervletet céloz meg, meghívja annak public void service (ServletRequest,
ServletResponse) metódusát. Az első paraméterként kapott objektumon
keresztül a kliens-szervlet, míg a második paraméterként kapott objetumon a
szervlet-kliens irányú kommunikáció valósítható meg. Tehát a szervlet a
kliens kérésével kapcsolatos információkat a service() metódusának első
paraméterében kapja meg, melyben egy javax.servlet.ServletRequest interfészt
implementáló objektumot kap. A szervlet ennek metódusait meghívva hozzájuthat
a kliens kérésében küldött információkhoz.
A szervlet tehát úgy szolgál ki egy kliens kérést, hogy feldolgozza az
esetleges kapott paramétereket, melyek rendszerint HTML űrlapok
használata esetén az űrlap mezőinek értékeit tartalmazzák, majd
dinamikusan legenerál (általában) egy HTML oldalt, melyet a kliens
böngészőprogram megjelenít. A ServletRequest interfész a klienskérés
paramétereinek és jellemzőinek, a kliens gép címének, a kérést
kiszolgáló szerver gép címének, valamint a kérés tartalmának olvasását
lehetővé tevő metódusokat definiál. A kérés tartalmát
adatfolyamként egy ServletInputStream objektum reprezentálja. HttpServlet
esetén a klienskérést egy HttpServletRequest objektum tartalmazza. HTML űrlapok tartalmát szintén paramétereken
keresztül kapja meg a szervlet. A paraméter neve a HTML űrlap beviteli
mezőjének nevével egyezik meg, a paraméter értéke pedig a beviteli
mező tartalmát veszi fel. Tehát csakis a névvel rendelkező beviteli
mezők értékét tudja átvenni a szervlet. A szervlet válaszát a service() metódusának második paraméterében levő
javax.servlet.ServletResponse interfészt implementáló objektum megfelelő
metódusait meghívva juttathatja vissza a klienséhez. A ServletResponse interfész a szervlet
válaszának jellemzőit beállító, valamint a válasz kiírását lehetővé
tevő metódusokat definiál. A válasz tartalmát adatfolyamként egy
ServletOutputStream objektum reprezentálja.
HttpServlet esetén a szervlet válaszát egy HttpServletResponse
objektum tartalmazza. A szervlet válaszát csak azután küldi el a webszerver,
miután lezártuk a választ reprezentáló adatfolyamot annak close metódusával.
Ha még a teljes adatfolyam lezárása előtt szeretnénk, hogy a kliens
böngészőprogram megkezdje az addig generált válasz megjelenítését, akkor
használjuk a ServletOutputStream flush metódusát. Ekkor a böngésző a
válasznak csak azon prefixét képes megjeleníteni, melynek grafikus
megjelenítése már nem fog megváltozni, tehát például, ha szöveg esetén
lezártuk azt egy sorvége jellel. Megjegyzendő, hogy HttpServletResponse
esetén a HTTP mező fejléceit csakis a válasz adatfolyamhoz történő
első hozzáférés előtt szabad állítani. Ha a válasz hosszát
előre tudjuk, akkor érdemes azt beállítani a setContentLength
metódussal, mivel ilyenkor a webszerver és a kliens közti adatátvitel sokkal
gyorsabb lesz |
Egy általánosan
használható szervlet ősosztály a javax.servlet.GenericServlet. Ez az
osztály implementálja mind a javax.servlet.Servlet, mind pedig a javax.servlet.ServletConfig interfészek metódusait. Biztosítja az init(), illetve a destroy() metódusok egy egyszerű implementációját. A getServletConfig() metódus visszaadja az init() metódus paraméterében kapott objektumpéldányt. A getServletContext() metódus az init() metódus paraméterében korábban kapott objektumot adja
vissza visszatérési értékként. A getServletInfo() metódus implementációja egy null értékkel tér vissza.
A származtatott osztályokban ezt illik felüldefiniálni úgy, hogy az
illető szervletről adjon vissza információkat (a szervlet nevét,
készítőjének nevét, a szervlet verziószámát, stb.) A service() metódus egy absztrakt metódus, vagyis a leszármazott
osztályok példányosíthatóságának érdekében a leszármazott osztályban felül
kell definiálni. |
A
javax.servlet és a javax.servlet.http csomagok architektúrája |
A javax.servlet osztályokat és interfészeket
bocsát rendelkezésünkre a szervletek írásához. A legfontosabb interfész a
Servlet interfész. Az összes szervletnek ezt az interfészt kell
implementálnia, legtöbbször a HttpServlet kiterjesztéseként. A Servlet interfész olyan metódusokat definiál, amelyek
segítségével kivitelezhető a kommunikáció a kliensekkel. Abban a
pillanatban amikor egy szervlet elfogadja a kapcsolatot egy klienssel, két
objektumot kap: · egy ServletRequest
objektumot, amelyik a kliens – szerver kommunikációért felelős · egy ServletResponse
objektumot, amelyik a szerver-kliens kommunikációért felelős. A ServletRequest interfész a következő dolgokat
bocsátja a szervlet rendelkezésére: · információkat a
klienstől kapott paraméterekről, a kliens által használt protokoll,
a hostnév, amelyiktől elfogadta a kérést · egy ServletInputStream
belépő fluxus. Ezt a szervlet a kliensektől kapott adatok
olvasására használja. A kliensek a HTTP protokoll PUT és POST metódusait
használják. A ServletResponse interfész metódusokat deklarál,
amelyek segítségével a szervlet válaszokat tud küldeni a kliensek kérdéseire. · biztosítja a válasz
hosszúságának meghatározását valamint ennek a MIME-kódját · biztosít egy
kimenő ServletOutputStream és egy Writer fluxust, amelyeken keresztül el
tudja küldeni a válaszokat a kérdésekre |
Egy szervlet inicializálása után a webszerver úgy
dönthet, hogy nincs többé szükség az adott szervlet szolgáltatásaira, és
megszünteti a szervlet példányt. Ilyenkor a szervlet futtatókörnyezet
megvárja, míg az adott szervletet használó minden még futó klienskiszolgáló
programszál véget ér (vagy egy beállított időtartam, általában 30
másodperc le nem telik), és meghívja a szervlet public void destroy()
metódusát. Ezen metódus meghívása után már nem fog egyik életciklus metódus
sem meghívódni. Előfordulhat, hogy ezen metódus már akkor meghívódik,
amikor a szervlet még egyetlen klienst sem szolgált ki, de az is
elképzelhető, hogy a destroy() meghívásának pillanatában esetleg még
több kliens kiszolgálása is folyamatban van. A túl hosszan tartó kiszolgálásból
eredő problémára megoldás lehet, ha mindig nyilvántartjuk, hogy
egyszerre hány programszál tartózkodik a kiszolgáló metódusban. A destroy
meghívásakor ezt egy logikai változóval jelezzük a programszálak felé, majd addig
várunk, míg számlálónk segítségével meg tudjuk állapítani, hogy minden
programszál befejeződött. A kiszolgálás menetét pedig felosztjuk apróbb
részfeladatokra, melyek befejezése után mindig megnézzük, hogy közben esetleg
meghívták-e a destroy-t. Igy elérhetjük, hogy minden futó programszál a
leggyorsabban reagál a szervlet
megszüntetésére, valamint a szervlet megszüntetése előtt, miután már
egyetlen programszál sem tartózkodik a kiszolgáló metódusban, biztonságosan
felszabadíthatjuk a szervletünk által foglalt erőforrásokat (például
adatbázis-kapcsolat lezárása). A szervlet megszüntetése után a szervletpéldány kikerül a szervlet futtatókörnyezet ellenőrzése alól. Ha esetleg újra szükség lenne egy már megszüntetett szervletre, akkor az a szervlet egy új példányának létrehozását és inicializálását vonja maga után. |
Folytatjuk... Finta Annamária |