40
Luku 7 RPC - TODO: write as text (not just list of items) Seuraavassa käsitellään RPC:tä (Remote Procedure Call), joka on ilmeisesti vanhin sokettien pääl- le rakennettu tapa tehdä hajautettuja sovelluksia. Käsittely on kohtuullisen pinnallinen ja se tehdään olettaen RMI tutuksi. 7.1 Taustaa Birrell & Nelson (1984) (vaikka “keskusteltu” jo aiemmin kirjallisuudessa). RFC 1057 (vähän ympäripyöreä). RPC:n (Remote Procedure Call) idea on välittää (TCP avulla) verkon yli proseduurin kutsu(ja) argumentteineen ja palauttaa takaisin etäällä suoritetun proseduurin tulos. Syy irrottaa proseduuri etäproseduuriksi liittyy yleensä työmäärään tai keskitettyyn suureen tietomäärään (jota ei ole järkevä kopioida moneen paikkaan). RPC:ssä, etäproseduurin kutsu näyttää ohjelmassa tavalliselta metodin kutsulta. Toteutus (kommunikointi verkon yli) on “näkymätön” ohjelmoijan kannalta. C-pohjainen – ei olioita kuten RMI:ssä. 7.2 Sovelluksen rakentaminen Paikallinen RPC-kutsu näyttää normaalilta kutsulta. Jotta tämä olisi mahdollista, todellista proseduuria vastaten pitää määrittää rajapinta ja sille toteutus paikalliseen koneeseen. Jokainen paikallinen RPC-kutsu on edustaproseduurin client stub kutsu, joka hoitaa kommuni- koinnin etäkoneen kanssa. Etäkoneessa (palvelimessa) on etäkutsupalvelin (server stub), joka odottaa etäkutsun tiedot si- sältäviä viestejä. Palvelin tulkitsee viestin ja suorittaa muistiavaruudessaan vastaavaan etäpro- seduurin palauttaen tuloksen takaisin. 65

RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

Luku 7

RPC

- TODO: write as text (not just list of items)

Seuraavassa käsitellään RPC:tä (Remote Procedure Call), joka on ilmeisesti vanhin sokettien pääl-le rakennettu tapa tehdä hajautettuja sovelluksia. Käsittely on kohtuullisen pinnallinen ja se tehdäänolettaen RMI tutuksi.

7.1 Taustaa

• Birrell & Nelson (1984)(vaikka “keskusteltu” jo aiemmin kirjallisuudessa).

• RFC 1057 (vähän ympäripyöreä).

• RPC:n (Remote Procedure Call) idea on välittää (TCP avulla) verkon yli proseduurin kutsu(ja)argumentteineen ja palauttaa takaisin etäällä suoritetunproseduurin tulos.

• Syy irrottaa proseduuri etäproseduuriksi liittyy yleensätyömäärään tai keskitettyyn suureentietomäärään (jota ei ole järkevä kopioida moneen paikkaan).

• RPC:ssä, etäproseduurin kutsu näyttää ohjelmassa tavalliselta metodin kutsulta.

• Toteutus (kommunikointi verkon yli) on “näkymätön” ohjelmoijan kannalta. C-pohjainen – eiolioita kuten RMI:ssä.

7.2 Sovelluksen rakentaminen

• Paikallinen RPC-kutsu näyttää normaalilta kutsulta.

• Jotta tämä olisi mahdollista, todellista proseduuria vastaten pitää määrittäärajapinta ja silletoteutus paikalliseen koneeseen.

• Jokainen paikallinen RPC-kutsu onedustaproseduurin client stubkutsu, joka hoitaa kommuni-koinnin etäkoneen kanssa.

• Etäkoneessa (palvelimessa) onetäkutsupalvelin(server stub), joka odottaa etäkutsun tiedot si-sältäviä viestejä. Palvelin tulkitsee viestin ja suorittaa muistiavaruudessaan vastaavaanetäpro-seduurinpalauttaen tuloksen takaisin.

65

Page 2: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

66 LUKU 7. RPC

• (Stub = tynkä)

1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja.

2. Edustaproseduuri koodaa parametrit viestiin ja lähettää viestin.

3. Etäkutsupalvelin ottaa viestin vastaan, purkaa sen ja kutsuu vastaavaa etäproseduuria.

4. Etäkutsupalvelin koodaa tuloksen viestiin ja lähettää sen takaisin.

5. Paikallinen edustaproseduuri ottaa viestin vastaan, purkaa tuloksen ja palauttaa sen paikalliselleohjelmalle.

6. (Edellisessä: synkroninen RPC-kutsu.)

ParametriongelmiaEtäproseduurikutsujen toteuttaminen olisi helppoa, jos kaikki parametriarvot olisivat skalaariar-

voja ja molemmat RPC-järjestelmät olisivat samoja.

• RPC-toteutukset perustuvat usein alla olevaan käyttöjärjestelmään ja siinä tiedon esitysmuotovoi vaihdella. Parametrien koodauksen (mashalling) täytyy ottaa tämä huomioon. (XDR)

• Jotkin paikalliset parametrit voivat olla viiteparametrejä. Jos sallittua, marshallointi tarkoittaaviitatun rakenteen kopiointia. Tulisiko muutosten heijastua takaisin? Mahdollista! Copy/restore-parametrit!

• Koneessa pitää olla RPC:n toteutus. Useita saatavilla. (Kokeile esim. Unixissa ’man rpcgen’.)

• Helpoin tapa tehdä RPC-sovellus on käyttää rajapintakieltä Interface Definition Language(IDL),jonka avulla määritellään kutsuttavien etäproseduurien muoto.

• Järkevää, koska IDL kuvausta käyttäen voidaangeneroidaedustaproseduuri ja etäkutsupalvelin(+muuta)!!

• rpcgen : ei IDL vaan RPC Language kuvaus rajapinnasta.

7.3 Esimerkki

Esimerkki: DCE RPC

• http://www.opengroup.org/dce/

• Open Software Foundation (OSF) on tehnyt RPC-toteutuksen nimeltä Distributed ComputingEnvironment useille käyttöjärjestelmille.

• DCE RPC tarjoaa välikerroksen käyttöjärjestelmän ja hajautettujen sovellusten välille.

• Seuraavan kalvon kuva näyttää, miten tehdä DCE RPC-sovellus käytännössä (asiakas- ja palve-linpää).

DCE RPC-sovellusten tekeminen

Page 3: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

7.3. ESIMERKKI 67

• IDL description + client code + server code = app.

• Rajapintakuvaus on kirjoitettu IDL-kielellä ja kuvaus on kaikkia yhteensitova “liima”.

• Jokaisella kuvauksella tulee olla yksikäsitteinen tunnistenumero.

• Asiakassidotaanetäkutsupalvelimeenhakemistopalvelunavulla.

• Palvelimessa on käynnissäDCE daemon, joka tunnistaa sisääntulevat RPC-viestit ja välittää neoikealle prosessille.

• Varsinainen RPC-kutsun toteutus on normaali: koodaus, viestin lähettäminen, purkaminen, pro-sessointi, (tuloksen) koodaus, lähettäminen, purkaminen.

Sun RPC-esimerkki

• Ei ilmeisesti ole aivan samanlainen kuin DCE RPC.

• Esimerkki (dice.x, dice_prog.c, rdice.c) on kurssin kotisivulla.

Miten käyttää esimerkkiä

• Generoi rajapinnatrpcgen dice.x

• Käännä clientgcc rdice.c dice_clnt.c -o dice_client -lnsl

• Käännä servergcc dice_prog.c dice_svc.c -o dice_server -lnsl

• Serverin käynnistys./dice_server

• Clientin käynnistys./dice_client staff.cs.utu.fi 10

dice.x

/ * dice.x: Remote random dice protocol * /program DICEPROG {

version DICEVERS {int GETDICE(string) = 1;

} = 1;} = 0x20000001;

Palvelimeen: dice_prog.c

Page 4: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

68 LUKU 7. RPC

/ ** dice_proc.c: implementation of the

* remote procedure "getdice"

* /

#include <stdio.h>#include "dice.h" / * dice.h generated by rpcgen * /#define RANDOM random

long random();

int * getdice_1_svc(char ** who, struct svc_req * req){

static int result; / * must be static! * /

result = (unsigned long int)(RANDOM()%6) + 1;printf("Sending %d back to %s\n", result, * who);return (&result);

}

Asiakas: rdice.c 1/3

/ ** rdice.c: main program for getting random dice numbers

* /

#include <stdio.h>#include "dice.h" / * dice.h generated by rpcgen * /

main(int argc, char ** argv) {CLIENT * clnt;int * result;char * server;int howmanytimes,i;

if (argc != 3) {fprintf(stderr, "usage: %s host number\n", argv[0]);exit(1);

}

Asiakas: rdice.c 2/3

server = argv[1];sscanf(argv[2],"%d",&howmanytimes);if (howmanytimes < 1) howmanytimes = 1;

// Create client "handle".

Page 5: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

7.4. HUOMIOITA JA YHTEENVETO 69

clnt = clnt_create(server, DICEPROG, DICEVERS, "tcp");

if (clnt == (CLIENT * )NULL) {// No connection establishedclnt_pcreateerror(server);exit(1);

}

Asiakas: rdice.c 3/3

// Call the remote procedurefor (i=0; i<howmanytimes; i++) {

result = getdice_1(&server, clnt);printf("Got %d \n", * result);

}

printf("Dice asking from %s done.\n", server);clnt_destroy( clnt );exit(0);

}

7.4 Huomioita ja yhteenveto

• RPC:n viestin voi tehdä itse.

• RPC:n kirjasto tarjoaa suuren määrään proseduureja asiakkaita ja palvelimia varten.

• Parametrien koodausstandardi: XDR (eXternal Data Representation).

• Asiakkaan ja palvelimen voi tehdä alusta alkaen itse tai ne voi toteutusympäristöstä riippuenosittain generoida.

• IDL-kieli on kohtuullisen rikas.

• DCE RPC:n IDL-kieli on toiminut pohjana Microsoftin COM:n (ja DCOM:n) IDL-kielelle (lä-hes identtinen).

• Kutsun ei tarvitse olla synkroninen – kutsuja voi jatkaa suoritustaan ja kun kutsu on valmis,kutsujalle “ilmoitetaan”.

• TCP:n tilalla voi olla jokin muu kuljetusmekanismi (XML-RPC: HTTP).

• RPC ei ole vain C-kielisille ohjelmille – esim. XML-RPC toteutuksia on useille kielille: Java,C/C++, Perl, PHP, Python.

• RPC on esitelty välitystekniikkana.

• Sovellusten tekemisen problematiikka samanlaista kuin RMI:n kohdallakin. Etäproseduurit ei-vät ole mitään aktiivista, vaan passiivisia palveluita.

• Ja yleisemmin monisäiesovellusten ongelmat koskien tiedon samanaikaista käsittelyä ovat myösRPC-sovellusten ongelmia.

Page 6: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

70 LUKU 7. RPC

Page 7: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

Luku 8

Verkkoprotokollat ja XML

Tässä luvussa perehdytään hiemaan XML:ään (eXtensible Markup Language) asiakas-palvelin sovel-lusten ohjelmoinnin ja ylipäänsä Java-kielen kannalta. Luvussa 8.2 pyritään selvittämään lukijalla,mikä XML on, mitä siihen liittyvät monet lyhenteet/käsitteet (XSL, DTD, skeema, . . . ) tarkoittavat, jamiten laajan kokonaisuuden XML itse asiassa muodostaa. Tämän oppimateriaalin puitteissa käsittelyjää hyvin pinnalliseksi — lukijan tulee hakea lisätietoja esim. W3C:n sivuilta (http://www.w3c.org ).

XML:n idea tämän oppimateriaalin ja luvun kannalta on toimia asiakas-palvelin sovellusten väli-sessä keskustelussa välitettävän datan esitysmuotona. Itse asiassa XML soveltuu myös hyvin tilantei-siin, joissa ohjelman eri suorituskertojen välillä pitää taltioida jotain tietoa tiedostoihin. Tämä on hyvinperusteltua sillä, vaikka Java-ohjelmien kesken onkin helppo välittää Java-olioita (ja Java-olioita voi-daan tallettaa tiedostoihin), niin sellainen menettely rajaa toiminnan Java-kielisiin ohjelmiin. Lisäksitällaiseen sarjallistamiseen liittyvä ongelma on, että sarjallistamisen purkamisen yhteydessä käytet-tävien luokkien täytyy olla muuttumattomia siihen nähden millaisia ne olivat sarjallistamisen tapah-tuessa. Usein esiintyvä tarve muuttaa ohjelmia ja niiden luokkia käytännössä laskee sarjallistamisenhyödyllisyyttä. XML:n merkitys tässä mielessä on toimia (ohjelmointi)kielestä ja suoritusalustastariippumattomana yleisenä datan esitysmuotona1.

Luvussa 8.3 tarkastellaan hieman XML:n käyttötilanteita —vaikka XML ei olekaan ohjelmoin-tikieli, niin osoittautuu, että sillä on Javankin yhteydessä käyttöä. Tämän materiaalin yhteydessäXML:ää tarkastellaan vain rakenteisen tiedon esittämisenvälineenä. Tätä XML:n osa-aluetta valoi-tetaan luvussa 8.4. Oliot edustavat rakenteista tietoa ja ohjelmointikieliessä tiedolla on jokin tyyppi— tilanne on samanlainen myös XML:n kohdalla. Luvussa 8.4 tarkastellaan tiedon esittämisen li-säksi tyypin, DTD = Document Type Definition, esittämistä. Tämän jälkeen luvussa 8.5 tarkastellaanhieman XML:ää Javan kannalta perehtymällä erityisesti DOM:iin (Document Object Model), jon-ka avulla XML-dokumentteja voidaan esittää Javan olioina.DOM on suunniteltu esittämisen lisäksiXML-tiedostojen jäsentämistä ajatellen (samalla myös käänteistä toimenpidettä, “antijäsentämistä”,ajatellen). DOM on itse asiassa pelkkä ohjelmointirajapinta XML-dokumenttien käsittelemiseksi —on myös kaksi muuta ohjelmointirajapintaa SAX (Simple API for XML) StAX (Streaming API forXML), mutta niitä ei tämän materiaalin puitteissa käsitellä. Luvussa 8.5 esitetään myös laajahko esi-merkki DOM:n soveltamisesta.

Tässä luvussa on ollut myös tarkoitus käsitellä verkkoprotokollien muodostamiseen liittyviä asioi-ta asiakkaan ja palvelimen kannalta. Erityisesti tarkoituksena oli pohtia, miten protokollan tilan tulisinäkyä asiakas- ja palvelinsovelluksissa, ja mitä luokkia protokollan muodostamisen yhteydessä tulisi

1Asiakkaan ja palvelimen välisiä viestejä suunniteltaessaniille voi toki keksiä itse täysin vapaamuotoisen tekstipohjaisenmuodon, mutta miksi tuolloin ei käyttäisi XML:ää?

71

Page 8: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

72 LUKU 8. VERKKOPROTOKOLLAT JA XML

muodostaa. Tässä oppimateriaalin versiossa nämä asiat ovat vain listamaisesti kalvojen pohjalta (eikirjoitettu auki).

8.1 Verkkoprotokollat

• Yleistä

• Protokolla asiakkaan ja palvelimen kannalta; tilat

• Kuvaaminen, Muodostaminen

• Protokollasta luokiksi

• Viime aikaisia suuntauksia

8.1.1 Taustaa

• Protokollia määritelty “pilvin pimein”.

• RFC (Request For Comments) 1 –http://www.ietf.org/rfc.html

Yli 3500 olemassa.

Esim. RFC 821: Simple Mail Transfer Protocol.

• Tyypillisesti Internetin alkuaikoina kuvattiin useiden tekstipohjaisten protokollien kaikkien vies-tien tarkka muoto sekä “keskustelun etenemistavat”.

• Hajautetun sovelluksen voidaan ajatella olevan jossain tilassa.

• Viesti(e)n lähettämisen seurauksena sovellus siirtyy tilasta toiseen.

• Vuoropohjaisissa protokollissa usein vähän vaihtoehtojaseuraavalle viestille (& tilasiirtymälle).

• Keskustelevien osapuolten pitää “mieltää” hajautetun sovelluksen olevan jossain tilassa ja hy-väksyä vain tilan kannalta lailliset viestit.

8.1.2 Protokollan muodostaminen ja kuvaaminen

Muodostaminen:

• Pitää miettiä läpi kaikki asiakkaan ja palvelimen väliset keskustelut.

• Kirjataan keskustelun vaiheet viesteiksi; vältä “turhia”viestejä.

• Pitäisi pyrkiä minimoimaan erilaisten viestien määrää.

• Tärkeää huomioida erilaiset kuittaukset sekä virhetilanteista ilmoittaminen.

• Todellisuudessa keskustelu ei aina etene niin kuin toivotaan: virheistä toipuminen eräs keskus-telun muoto (viestejä).

Viestien koodaus:

Page 9: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.1. VERKKOPROTOKOLLAT 73

• Binäärisessä muodossa, esim. kirjoitetaan olioita TCP-sokettien tiedostovirran päällä.

• Tekstimuodossa (perinteinen vaihtoehto): suunnitellaanitse viestien muoto ja koodaus.

• Moderni variaatio: esitetään viestit XML:llä.

Kaikkien edellisten vaihtoehtojen yhteydessä on hyvinkinjärkevää esittää viestit ohjelmassa eri-laisilla Java-olioilla.

• Muodostetaan sovellukselle tiloja.

• Tilat ovat hajautetun järjestelmän kokonaistiloja, muttausein liittyvät johonkin osapuoleen.

• Tilakaavio: Tilasta toiseen siirrytään vaihtamalla viestejä – tekemällä keskustelu.

• Yksittäiset tilasiirtymät (keskustelu) voidaan kuvata UML:n sekvenssikaaviolla.

• Yleisemmin sekvenssikaaviolla voidaan kuvata tyypillisiä keskusteluja.

autentikointiodot. yhteyd.otto

kyselytilaodotetaanautentikointia

kyselyjen palvelu

login

login fail

login ok

logout

logout

logout logout ok

close conn.

close ok

tehdään logout

lopetustilalopetustila

login ok

tee yhteys

yhteys tehty

yhteys tehty

tee kyselykyselyn tulos

Kuva 8.1: Eräs mahdollinen tilakaavio.

8.1.3 Protokollista luokiksi

• Perusajatus: Luetellaan kaikki järjestelmässä tarvittavat viestit jatehdään jokaista vastaten yksiluokka.

• Tehdään yksi yliluokka, joka määrittää yleiset ominaisuudet.

• Niitä lähinnä decode/encode (tai read/write tai parse/unparse).

• Yksittäisiä viestejä vastaavat aliluokat toteuttavat lisäksi havainnointi- ja modifiointimetodeja.

Pohditaan esimerkkiä, jossa henkilöiden tietoja haetaan palvelimelta. Ensin pitää onnistuneestiautentikoida. Sitten voidaan tehdä useita kyselyjä. Lopuksi suljetaan yhteys palvelimeen. Tarkoituslinkittää IT-laitoksen henkilötietokantaan.

Page 10: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

74 LUKU 8. VERKKOPROTOKOLLAT JA XML

autentikointi

kyselytila

logout

tee yhteys

onnistunut login

epäonnistunutlogin

onnistunutkysely

epäonnistuvakysely

lopetustila

logout

tehdään logout

yhteyden sulkeminen

Kuva 8.2: Tilakaavio asiakkaan kannalta.

• A 7→ P: Tee autentikointiyritys

• P 7→ A: Autentikointi onnistui

• P 7→ A: Autentikointi epäonnistui

• P 7→ A: Autentikointi suoritettu jo

• A 7→ P: Anna ilmoitetun henkilön tiedot

• P 7→ A: Palautetaan halutut tiedot

• P 7→ A: Kyseistä henkilöä ei ole

• A 7→ P: Sulje yhteys

• P 7→ A: Yhteys sulkeutuu

• . . .

Kustakin luokka + yliluokka XXX_App_Message.

import org.w3c.dom. ∗;

public abstract classITinfo_Message {

public abstract ITinfo_Message parse(Document doc);

public abstract void unparse(Document doc);

} // class ITinfo_Message

import org.w3c.dom. ∗;

public classITinfo_Login_Message {

Page 11: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.1. VERKKOPROTOKOLLAT 75

odot. yhteyd.otto

odotetaanautentikointia

kyselyjen palvelu

logout

lopetustila

login ok

yhteys tehty

palvellaankyselypyyntö

Kuva 8.3: Tilakaavio palvelimen kannalta.

private String user;// tunnusprivate String passwd;// salasana

public ITinfo_Login_Message(String u, String p) {// tarkistuksia ... (poissa)user = u;passwd = p;

} // ITinfo_Login_Message

public String getUser() {return user; }

public String getPasswd() {return passwd; }

public void setUser(String u) { user = u; }

public void setPasswd(String p) { passwd = p; }

public ITinfo_Message parse(Document doc) {// jäsennetään DOM:sta ITinfo_Login_MessageString p = ;String u = ;// ... luetaan arvot u:lle ja p:llereturn new ITinfo_Login_Message(u,p);

} // parse

public abstract void unparse(Document doc) {// muodostetaan rakenne tyhjään dokumenttiin ...

} // unparse

} // class ITinfo_Login_Message

Mahdollisesti uloin kuori pois + pitäisi tehdä DTD-määrittely.

8.1.4 Uusia painotuksia: REST- ja ohut käyttöliittymä-tekniikat

Protokollaa ja ylipäänsä järjestelmän toimintaa suunniteltaessa olennaista päättää missä tilatietoa yl-läpidetään.

Page 12: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

76 LUKU 8. VERKKOPROTOKOLLAT JA XML

: asiakas : palvelin

LOGIN−viesti

LOGINOK−viesti

kyselytila

kyselytila

tila tilaautentikointi−autentikointi−

onnistunutlogin

Kuva 8.4: Keskustelu sekvenssikaaviona.

• Perinteinen ratkaisu: pidetään tilatietoa sekä asiakkaissa että palvelimissa.

• Thin client: pidetään kaikki tieto palvelimessa.

• Rest = representational state transfer: pidetään kaikki tilatietoyhteydestäasiakkaassa.

Ohut asiakas -tekniikka:

• Lähinnä käyttöliittymätekniikka, koska koko sovellus on oikeastaan palvelimessa.

• Ajax on yksi toteutuskeino. Toimii web-alustan yhteydessä. Useita toteutuksia saatavilla. Pe-rustuu web-sivun sisällön dynaamiseen muuttamiseen ilmansivun uudelleenlataamista.

• Esim. Vaadin (IT Mill Oy).

• Ohut asiakas -tekniikkaa täydentää pilvilaskenta.

REST-tekniikka:

• Palvelimella hajautetun järjestelmän tilatietoa, mutta kaikki asiakasyhteyteen liittyvä tieto asiak-kaalla (toimitetaan pyyntöjen mukana palvelimelle).

• Asiakas-palvelin-suhde ontilaton: palvelin on aina “levossa” ja palvelee yksittäisen pyynnönkerrallaan.

• Tuloksiin voidaan soveltaavälimuistiin taltiointia.

• Muita periaatteita: layered design, uniform interfaces jacode-on-demand.

8.2 Johdatus XML:ään

Mikä XML oikein on? XML on alunperin kehitetty tuomaan rakennetta WWW:n sisältöön, rakennet-ta HTML-sivujen “latteuden” tilalle. HTML-kielen tapaan varsinainen XML-kieli (joskin XML on

Page 13: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.2. JOHDATUS XML:ÄÄN 77

lopetustila

kyselytila

autentikointitilaepäonnistunutautentikointi

kyselyn tekeminen

kytkeytyminen

login

logout

lopettaminen

laitontoimenpide

toimenpidelaiton

logout

Kuva 8.5: ITinfo: tilakaavio asiakkaasta.

<?xml version="1.0" standalone="yes"?><itinfo_message><itinfo_login_message>

<user> villep </user><passwd> salainen </passwd>

</itinfo_login_message></itinfo_message>

Kuva 8.6: ITinfo_Login_Message XML:nä.

myös paljon muutakin) on myös ns. merkkauskieli — eli pelkistetysti ilmaistuna tekstin osiin, osa-kokonaisuuksiin, on mahdollista liittää tietynlainen merkitys merkkauksen avulla. HTML:ssä merk-kauksen tarkoituksena on lähinnä muotoilun ilmaiseminen (samantapainen tilanne on mm. LaTeX:nkohdalla). XML on johdettu yleisestä SGML:stä (Standard Generalized Markup Language). XML onSGML:ään yksinkertaisempi, spesifisempi.

XML-kieli on rakenteisen tiedon kuvauskieli. XML-dokumenttikuvaa yhden rakenteisen tietoal-kion. XML pyrkii myös antamaan merkityksen kuvatulle tiedolle — joskaan tässä ei tarkoiteta mitäänyrityksiä ilmaista kuvattavien asioiden semantiikka formaalisti, vaan ideana on, että voidaan itse luo-da tietynlainen sanasto (jonka sanoihin ajatellaan liittyvän semanttinen merkitys) ja tuota sanastoakäyttäen dokumentin osille annetaan merkitys.

Yleisesti XML onjoukko tekniikkojatiedonkuvaamiseksi, käsittelemiseksijaesittämiseksi. XML:äänliittyy useita laajoja kokonaisuuksia — varsinainen XML-kieli muodostaa hyvin pienen osan. Esi-merkiksi XSL, eXtensible Style Language, on tarkoitettu XML-dokumenttien ulkoasun kuvaamisek-si. Yhdelle dokumentille voidaan eri julkaisualustoja varten määritellä XSL-kielinen kuvaus, jonkaavulla XML-dokumentista johdetaan kyseisen alustan mukainen (sen rajoituksiin sopeutuva) esitys.XSL:n on itse asiassa menetelmä muuttaa dokumentteja yhdestä rakenteisesta esityksestä toiseen.XSL:ää ei tämän materiaalin puitteissa käsitellä (vaikka Javalla onkin mahdollista lukea ja käsitellämyös XSL-kuvauksia XML-dokumenttien yhteydessä), sillä XSL suuntautuu dokumenttien muotoi-

Page 14: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

78 LUKU 8. VERKKOPROTOKOLLAT JA XML

luun.XML on suunniteltu WWW:stä lähtöisin, mutta kuten todettu,se soveltuu muuallekin. XML:n

kehittämistä johtaa W3C (World Wide Web Consortium,www.w3c.org ). W3C:hen kuuluu n. 500jäsenorganisaatiota, ja sen perusti Tim Berners-Lee vuonna 1994. W3C:n takana on paljon isoja or-ganisaatioita ja yrityksiä (mm. MIT, CERN, DARPA, EU, Nokia, Sun, Microsoft, HUT, HY, . . . ).XML:n kehitystyö alkoi 1990-luvun puolivälissä.

XML 1.0 on W3C:nsuositus(helmikuu 1998; korjattu versio, lokakuu 2000). Itse asiassa XML1.1 on jo “julkaistu”, mutta siitä ei ole vielä tehty suositusta. Vaikka ’suositus’ (engl. recommenda-tion) kuulostaa hieman vähäpätöiseltä, niin se on W3C:n asteikolla korkein status ja sen voi rinnastaastandardin määrittelyyn. XML-kielen suosituksen lisäksiW3C on antanut suosituksen useista kymme-nistä XML:ään liittyvistä osakokonaisuuksista. Lisäksi W3C:llä on useita työryhmiä XML:stä tälläkinhetkellä — ilmeisesti asioiden laajuudesta johtuen kehitystyö ainakin vaikuttaa hieman hitaalta.

Lopuksi W3C:n oma näkemys XML:n olemuksesta, “XML in 10 points”:

1. Tiedon strukturointi. Strukturointia on nykyään kaikkialla: tietokannan tietue, OO-kielen olio,. . .

2. XML-kieli on HTML-kielen tapainenkuvauskieli.

3. XML-dokumentti ontekstipohjainen kuvaus, jota ei ole tarkoitettu luettavaksi ihmisten toimes-ta.

4. Havainnollisuus: Kuvauksia voi tehdä käsin (ja XML-dokumentteja voi jopa lukea). Tekstuaa-lisesta esityksestä seuraavaan havainnollisuuden haittapuoli on dokumenttien suuri koko, muttasiihen voi välittämisen yhteydessä vaikuttaa tiivistyksellä.

5. Joukko teknologioitakuvauskielen lisäksi.

6. XML on suhteellisen uusiasia; SGML on ISO-standardi, 1980-luvun alkupuoli.

7. XML: HTML 7→ XHTML (uusi kieli WWW-sivuille).

8. XML-dokumentilla voi olla tyyppi; tyypin voi koostaa modulaarisesti.

9. XML toimii semanttisen webin perustana.

10. XML on lisenssivapaa, alustariippumaton ja hyvin tuettu.

8.3 XML:n käyttötilanteista

Seuraavassa luonnehdintoja XML-dokumenttien esittämisestä, välittämisestä, jäsentämisestä ja tuot-tamisesta.

XML-dokumenttien esittäminen

XML-dokumentteja halutaan tyypillisesti esittää useillaerilaisilla alustoilla. Alustoista WWW-selainon luonnollisesti tällä hetkellä kiinnostavin. Esittäminen vaatii tuekseen XSL-määrityksen. Kuvassa8.7 on havainnollistettu kahta tapaa katsoa XML-dokumentteja WWW-selaimen avulla: joko suoraantai XML/HTML-konversion kautta. Nykyään monet selaimet tukevat jo suoraa XML-dokumenttienesittämistä

Page 15: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.3. XML:N KÄYTTÖTILANTEISTA 79

XML

XSL

konversio−ohjelma

HTML+

muuta

www−selain

XML

XSL

XML−pohj.verkkoselain

(CSS)

Kuva 8.7: XML-dokumenttien esittämisestä.

XML-dokumenttien välittäminen

Välittämistilanne liittyy suoraviivaisesti asiakas-palvelin sovelluksiin. XML-dokumentti toimii tiedonesittämismenetelmänä. Osapuolten pitää sopia dokumenttien muodosta jamerkityksestä. Tässä yhtey-dessä on luonnollista määrittää DTD-kuvaus välitettävälle tiedolle. Valitettavasti XML-kielen mu-kaisten dokumenttien ei tarvitse noudattaa mitään tyyppikuvausta (DTD:tä tai skeemaa), mutta ilmansopimusta (siis tyyppi-ilmausta) välitettävän tiedon muodosta, välitettävän tiedon käyttökelpoisuuson hyvin kyseenalaista.

XML−dokumentti

DTD

sovellus Bsovellus A

Kuva 8.8: XML-dokumenttien välittämisestä.

Page 16: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

80 LUKU 8. VERKKOPROTOKOLLAT JA XML

XML-dokumenttien jäsentäminen

Kun XML-dokumentteja käsitellään ohjelmallisesti (kuva 8.9), niin vastaanottavan ohjelman pitääpystyä jäsentämään XML-dokumentti, Javan tapauksessa olioiksi ohjelman muistiavaruuteen. Javanyhteydessä tarjolla on useita jäsentäjiä. Luvussa 8.5 perehdytään Apache XML-projektin tuloksenasyntyneeseen Xerces-jäsentäjään. Sen avulla voi myös tehdä jäsentämisen käänteistoiminnon (“an-tijäsentäminen”), eli oliomuotoisen XML-dokumentin esityksen purkamisen tekstimuotoon. Xercesperustuu DOM:iin (ja SAX:iin) — tietyssä mielessä DOM on tapa käydä läpi oliomuotoinen XML-dokumentti.

dokumenttiXML−

jäsentäjäXML−

XML−olioita

sovellus

Kuva 8.9: XML-dokumenttien jäsentäminen.

XML-dokumenttien tuottaminen

XML-dokumenttien tuottamiseksi on useita tapoja. On jopa erityisiä editoreita, jotka tukevat do-kumenttien tekemistä “käsin”. Yleisempi XML-dokumentin muodostumistapa on kuitenkin itsenäi-nen ohjelma, joka käyttäjä tietojen perusteella tekee ohjelmallisesti XML-dokumentin (DOM, Java).XML-dokumentteja voidaan helposti muodostaa esimerkiksiapplettien, servlettien, JSP:n, HTML-lomakkeet + CGI-ohjelmien, jne yhteydessä. Usein XML-dokumentti generoidaan osittain tietokan-nan tietojen perusteella.

Tietokannan rooli XML:n yhteydessä on merkittävä, koska tietokantojen tarkoitushan on samanta-painen: tiedon esittäminen. Tietokantojen (erityisesti myös relaatiotietokantojen) valmistajat tukevatnykyään hyvin XML:ää ja saatavilla on jopa erityisiä XML-tietokantoja, joihin voi taltioida XML-dokumentteja.

XML ja verkkoviestintä

XML liittyy dynaamiseen sisällön tuottamiseen kuten servletit, JSP, ASP, jne. XML:n rooli ontiedonsisällönesittämisessä – ei niinkään ulkoasun esittämisessä (vaikka siihen on toki myös panostettu).XML:n alkuperäinen tarkoitus ei ole ilmaista, mistä tieto koostetaan, vaan XML-dokumentti toimiiitse tiedon koosteena. XML ei ole verkkolomake, vaan pikemminkin verkkolomakkeen täyttämisen“tulos”.

Page 17: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.4. TIEDON ESITTÄMINEN XML:LLÄ 81

8.4 Tiedon esittäminen XML:llä

XML-dokumentin rakennetta voi lähestyä tarkastelemalla HTML-dokumentin tagi-rakennetta:

<html><title> Sivun otsikko </title><body> <h1> Pääotsikko </h1>

Tekijä on <b>L. Auri</b> ... <p>...</body></html>

HTML-dokumentissa tageilla on sulkumainen rakenne, sama sulkurakenne on XML-dokumenteil-la. HTML:n ongelmaksi XML:n kannalta nähdään esimerkiksi tagiparin <b> ... </b> sisällä olevantiedon merkitys — <b> ... </b> on vain tiedon muotoiluun liittyvä määritys (bold face), se ei otakantaa sisältöön. XML-dokumenteilla on myös hierarkinen sulkumainen tagi-rakenne, mutta tageillaajatellaan nyt olevansemanttinen merkitys— erityisesti tällä ymmärretään sitä, että tagien merkitysei liity muotoiluun.

Seuraavassa esimerkissä 8.1 on esitetty eräänlainen sähköpostiviesti rakenteisena XML-dokumenttina.Aluksi on muutamia XML-dokumenttiin liittyviä määrityksiä, mutta sen jälkeen tiedoston sisältönäon vain hierarkinen sulkumaista järjestystä noudattava tagi-rakenne.

Page 18: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

82 LUKU 8. VERKKOPROTOKOLLAT JA XML

Esimerkki 8.1 Eräänlainen sähköpostiviesti XML-dokumenttina,sposti.xml .

<?xml version="1.0" ?><?xml-stylesheet type="text/xsl" href="sposti.xsl" ?><!DOCTYPE sposti SYSTEM "./sposti.dtd"><sposti><lahettaja>

<email> [email protected] </email><nimi> Ville Leppanen </nimi>

</lahettaja><vastaanottajat>

<vastaanottaja><email> [email protected] </email>

</vastaanottaja><vastaanottaja>

<email> [email protected] </email></vastaanottaja>

</vastaanottajat><otsikko> Koeviesti </otsikko><runko>

<kappale> Heips! </kappale><kappale> Olin muuten .... </kappale>

</runko></sposti>

Kuvassa 8.10 on esitetty esimerkin 8.1 dokumentti puurakenteena. Kuva esittää dokumenttia vainosittain, jotkin solmut puuttuvat kuvasta.

lähettäjä otsikko runkovastaaottajat

dokumentti

sähköposti

email

nimi

Ville.L...

Ville

kappale kappale

Heips! Olin ...email

vastaanottaja

hannu@..

heikki@..

Kuva 8.10: Esimerkkidokumentti puurakenteena.

Page 19: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.4. TIEDON ESITTÄMINEN XML:LLÄ 83

XML-dokumentti koostuu yhdestä (juuri)elementistä(tagi-pari), jolla on “tyyppinimi". Elementitkoostuvat hierarkisesti XML-elementeistä ja/tai tekstistä. Samannimisiä elementtejä voi yhden ele-mentin sisällä olla useita. Elementti≈ olion/tietokannan kenttä (pikemminkin kentän tyyppi). XML-dokumentti≈ oliokielen olio≈ Pascalin tietue≈ relaatiotietokannan tietue.

Periaatteessa XML-dokumentissa olevien elementtien nimet voidaan valita täysin vapaasti. Jos ta-git noudattavat hierarkista rakennetta ja dokumentissa onvain yksi juurielementti, niin dokumentti onoikeanmuotoinentai hyvinmuodostettu(well-formed) XML-dokumentti. Nimien on tarkoitus liittäätagi-parin sisällä olevalle tiedolle merkitys — tapahtuuko näin, kun kerran elementtien nimet voidaanvalita vapaasti? Ratkaisun tähän pyrkii muodostamaan dokumentin DTD-kuvaus; huomaa, miten esi-merkin 8.1 alussa on viittaus DTD-kuvaukseen (sposti.dtd).

Elementeillä voi olla myös tekstiarvoisianimettyjä attribuutteja, esimerkiksi seuraavaan tapaan:

<kappale tasaus="both">Tämä tasataan molempiinreunoihin ...

</kappale>

Attribuuttien nimet voi myös itse määrittää. Niiden arvonaon jokin merkkijono. Elementillä ei olepakko olla sisältöä, jolloin ainoa mahdollinen elementtiin liittyvä tieto on elementin attribuuteissa:

<graphic source="kissa.gif"/>

8.4.1 DTD = Document Type Definition

DTD on dokumentin rakennemääritys ja se on verrattavissa ohjelmointikielissä tyyppiin. DTD:n teke-miseksi on oma “kieli”, joka on osa XML:ää. DTD on niin laaja,ettei sitä tässä kuvata yksityiskohtai-sesti — toisaalta DTD on XML:n kannalta osoittautunut kuvausvoimaltaan hieman liian rajoittuneeksija sen takia XML:n yhteyteen on määritelty ns. skeemat (engl. scheme). Skeemoja voisi luonnehtiadokumenttien luokkakuvauksiksi — skeemoihin liittyvä kuvauskieli on DTD:n vastaavaa rikkaampi.

Vaikka DTD-kuvaus onkin tärkeä, niin on hyvä muistaa, että XML-dokumentin ei tarvitse ollaminkään DTD:n mukainen! DTD:n tarkoitus on määritellä, millaisia elementtejä XML-dokumentissavoi olla, ja mikä täsmällisesti ilmaistuna on niiden rakenne. DTD-kuvaus kuvaa myös elementteihinliittyvät mahdolliset attribuuttimääritykset. Jos dokumentin rakenne vastaa DTD:tä, XML-dokumenttiasanotaanvalidiksi (engl. valid).

DTD-määreitä on kahdenlaisia: ulkoisia ja sisäisiä. XML-dokumentin alussa voi ollaulkoisenDTD:n määre (DOCTYPE-kohta):

<?xml version="1.0"><!DOCTYPE sähköposti SYSTEM "/home/dtd/sposti.dtd"><sähköposti>

....</sähköposti>

Toisaalta XML-dokumentin alussa voi olla myössisäinenDTD-määre (samoin DOCTYPE-kohdassa):

<?xml version="1.0"><!DOCTYPE sähköposti [

<!ELEMENT sähköposti (lähettäjä, vastaanottajat, otsikk o, runko)><!ELEMENT lähettäjä (email, nimi?)>

Page 20: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

84 LUKU 8. VERKKOPROTOKOLLAT JA XML

...]>

<sähköposti>....

</sähköposti>

DTD-määritys on pääasiallisesti luettelo ELEMENT-määrittelyitä. ELEMENT-määrittelyiden apu-na käytetään ENTITY-määreitä, jotka ovat “vakioita” / “makroja” / viittauksia ulkoisiin tiedostoi-hin (esimerkiksi toisiin XML-dokumentteihin). ENTITY-määreitä on myös kahdenlaisia, mutta nii-den idea on toimia tietynlaisena vakioarvoisena lausekkeena. DTD:ssä lauseke määritellään ja XML-dokumentissa sitä voidaan käyttää — tuolloin kyseiseen kohtaan XML-dokumenttia “laajennetaan”ENTITY-viittauksen arvo.

Esimerkki 8.2 Sähköpostiviestiä vastaava DTD-määrittely,sposti.dtd .

<?xml version="1.0" ?><!ELEMENT sposti (lahettaja, vastaanottajat, otsikko, ru nko)><!ELEMENT lahettaja (email, nimi?)><!ELEMENT email (#PCDATA)><!ELEMENT nimi (#PCDATA)><!ELEMENT vastaanottajat (vastaanottaja)+><!ELEMENT vastaanottaja (email | nimi)><!ELEMENT otsikko (#PCDATA)><!ELEMENT runko (kappale) * ><!ELEMENT kappale (#PCDATA)>

Esimerkissä 8.2 on esitetty esimerkkiä 8.1 vastaava DTD-määritys (ulkoisena kuvauksena). DTD-kuvauksessa ELEMENT-osat ovat tavallaan kielioppikuvauksia ajatellen nonterminaaleja, joille anne-taan kuvauksessa “korvaussääntö”. Määreissä merkki ’|’ tarkoittaa ’tai’:ta; merkki ’?’ tarkoittaa, ettäkyseinen elementti voi olla ko. kohdassa tasan kerran tai puuttua kokonaan; merkki ’+’ puolestaan tar-koittaa, että kyseinen elementti esiintyy mahdollisesti useita kertoja, mutta kuitenkin vähintään ker-ran; merkki ’*’ kertoo vastaavasti toistosta, mutta nyt toistojen määrä on ’≥ 0’. Peräkkäin esiintyvienelmenttien listassa (A, B, C) järjestys on sidottu. Kentän tyyppi voi olla monikko (nonterminaaleja),EMPTY (elementillä ei sisältöä), ANY (mikä tahansa kelpaa sisällöksi) tai #PCDATA (merkkijono).

Edellisten lisäksi DTD-kuvauksessa on <!ATTLIST ...>-määreitä, joiden avulla määritellään ele-mentteihin liittyvien attribuuttien muoto, esimerkiksi seuraavasti:

<!ATTLIST book id ID #REQUIRED>

Jolloin määritellään, että elementtiin nimeltä ’book’ liittyy ’id’-niminen attribuutti, jonka arvonaon yksikäsitteinen identifioiva merkkijono. Määreistä #REQUIRED tarkoittaa, että attribuutti vaa-ditaan, mm. #IMPLIED tarkoittaa, että sovellus päättää arvon, ja #FIXED tarkoittaa, että XML-dokumenteissa kyseisellä attribuutilla on kiinteä arvo, joka ilmoitetaan DTD-kuvauksen yhteydessä.Muita tyyppejä ID:n lisäksi ovat mm. IDREF — viittaa ID:hen (täytyy olla olemassa) ja ENTITY —DTD:ssä määrätty entiteetti.

Entiteetit voivat ollaulkoisia jäsentämättömiaentiteettejä:

<!ENTITY kustantajanLogo SYSTEM "../pics/logo.gif" NDAT A gif>

Page 21: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.5. XML JA JAVA 85

jotka viittaavat johonkin ulkoiseen tiedostoon taiyleisentiteettejä:

<!ENTITY XML "Extensible Markup Language">

joihin XML-dokumentissa voidaan viitata ilmauksella ’&XML;’.

8.5 XML ja Java

DOM, Document Object Model, on W3C:n toimesta määritetty API XML-dokumenttien käsittelemi-seksi. Sunin JDK:n osana on myös Java-kielinen API DOM:lle (JDK 1.4:org.w3c.dom -paketti).Javan kannalta DOM on lähinnä joukko rajapintaluokkia, joiden avulla kuvataan XML-dokumenttienpuurakenne ja mahdollistetaan sen käyminen läpi. DOM ei siis oikeastaan ole jäsennin, vaan jäsen-nyksen tulos. DOM:a voidaan käyttää ohjelmalliseen XML-dokumenttien muodostamiseen & muok-kaamiseen. DOM:n haittapuolena on, että sen yhteydessä dokumentti ajatellaan muodostettavan koko-naan muistiin ennen käsittelyä. Toinen rajapinta SAX, Simple API for XML (pakettiorg.xml.sax ),toimii hieman toisella ajatuksella. Siinä jäsentäminen / läpikäynti etenee tapahtumapohjaisesti ja tar-koituksena ei ole muodostaa koko XML-dokumenttia vastaavaa oliorakennetta ohjelman muistiin.

8.5.1 DOM:n luokista

DOM:iin liittyy joukko luokkia, joista seuraavassa lyhyt luonnehdinta:

⋄ Element — XML-dokumentin elementti.

⋄ Attr — attribuutti.

⋄ Comment — <!-- Kommentti..... -->

⋄ Entity — entiteettiviittaus (ei määrittely).

⋄ Document — koko XML-dokumentti.

⋄ DocumentType — DTD-määrittely.

⋄ Text — tekstitietoa.

⋄ CDATASection — tekstiä (CDATA).

⋄ Node — puurakenne edellisille (yliluokka).

Edellisistä luokkaNode lienee keskeisin, sillä muut ovat sen aliluokkia — se määrittelee siis puumuo-don ja samalla yleisen toiminnallisuuden erityyppisille XML-dokumenttia esitävän puun solmuille.Taulukossa 8.1 on lueteltu joitakin luokanNode metodeja.

8.5.2 Jäsentäminen Xercesillä

Xerces on XML Apache-projektin tulos; se on DOM 1.0:n mukainen jäsentäjä. Xercesin avulla tuo-tetaan ajonaikainen esitys XML-dokumentista Java-olioina. Jotta tämä olisi mahdollista, Xerces:n mu-kana tulee toteutus DOM:n rajapintaluokille — antaa siis toteutuksen JDK 1.4:n paketilleorg.w3c.dom(ja javax.xml.parsers ). Jäsennyksen tuloksena syntyyorg.w3c.dom .Document-tyyppinenolio. Xerces tukee XML-dokumentin validointia, vaikka sitä ei esimerkeissä 8.3 — 8.5 hyödyn-netäkään. XML Apache:een liittyy myös Xalan, jolla voidaankäsitellä XSL-määrityksiä. Xerces-jäsentäjän täyttäminen näkyy ohjelmakoodissa esimerkiksi seuraavasti:

Page 22: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

86 LUKU 8. VERKKOPROTOKOLLAT JA XML

Node getFirstChild() — Puun solmun ensimmäinen lapsisolmu (solmuilla dokumentin mukainen jär-jestys;null, jos ei ole).

Node getNextSibling() — Nykyisen solmun seuraava sisarus, eli isäsolmun kannalta seuraava lapsi-solmu (null, jos ei ole).

Node getPreviousSibling() — Nykyisen solmua edeltävä sisarus,eli isäsolmun kannalta edeltävälapsisolmu (null, jos ei ole).

Node getLastChild() — Solmun viimeinen lapsisolmu (null, jos ei ole).Node getParentNode() — Solmun isäsolmu.NodeList getChildNodes() — Solmun kaikki lapsisolmut listamuodossa.String getNodeName() — Solmun nimi; nimi vaihtelee esitettävän asian mukaan. Esim. elementeillä

se on elementin nimi.String getNodeValue() — Solmun arvo; vaihtelee esitettävän asianmukaan. Esim. elementeillä tämä

on ainanull, sillä jos niiden arvona XML-dokumentissa tekstiä, niin kyseinen teksti on solmunlapsisolmussa, joka onText-tyyppinen.

NamedNodeMap getAttributes() — Vain elementeille; palauttaa attribuutit.boolean hasAttributes() — Onko elementillä attribuutteja?boolean hasChildNodes() — Onko solmulla lapsisolmuja?

⋆ Lisäksi monia muita metodeja; esimerkiksi muuttaminen: appendChild, removeChild,replaceChild, setNodeValue, . . .

Taulukko 8.1: Joitakin luokanNode metodeja.

import org.apache.xerces.parsers.DOMParser;import org.w3c.dom.Document;import org.xml.sax.SAXException;import java.io.IOException;

...String xmlFile = "file:///omatdatat/sposti.xml";DOMParser parser = new DOMParser();try { parser.parse(xmlFile);}

catch (SAXException se) { se.printStackTrace(); }catch (IOException ioe) { ioe.printStackTrace();}

...Document document = parser.getDocument();

Seuraavissa esimerkeissä 8.3 — 8.5 näytetään, miten palvelinsovellus voi ottaa vastaan XML-pohjaisen viestin, jäsentää sen ja selvittää jäsennyksen tuloksesta erilaisia tietoja. Asiakassovellus(esimerkki 8.4) lukee tiedostosta XML-dokumentin (sposti.xml ) jäsentämällä sen olioiksi. Ky-seisen esityksen se lähettää palvelimelle purkamalla sen taas tekstimuotoon. Luokka ’XMLsposti’(esimerkki 8.5) on aika yllätyksetön kuvaus siitä, miten XML-dokumentti jäsennetään kuvauksen lo-pussa olevien luokkien mukaisiksi olioiksi (DOM-olioista) ja vastaavasti “puretaan” ko. oliomuodostaDOM:n mukaiseksi puurakenteeksi.

Page 23: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.5. XML JA JAVA 87

Esimerkki 8.3 Palvelin, joka ottaa vastaan viestinXML-muodossa.

import java.io. ∗;import java.net. ∗;import java.util. ∗;public classViestiPalvelin {

public static final int VIESTIPORTTI = 8203;public static void main(String[] args)throws Exception {

ServerSocket ss =newServerSocket(VIESTIPORTTI);while (true) {

Socket cs = ss.accept();System.out.println("Connection from " + cs.getInetAddress() +"port " + cs.getPort());InputStream iS = cs.getInputStream();Sposti sp = XMLsposti.parse(iS);System.out.println("Message from " + sp.lähettäjä.email);iS.close(); cs.close();} // while

} // main} // class ViestiPalvelin

Esimerkki 8.4 Asiakassovellus, joka jäsentää tiedostosta XML-muotoisen viestin ja lähettää sen palveli-melle.

import java.net. ∗;import java.io. ∗;public classViestittaja {

public static void main(String[] args)throws Exception {if (args.length6= 2) {

System.out.println("Usage: java Viestittaja <host > <xml-message >" );System.exit(0);

}InputStream in =new FileInputStream(args[1]);Sposti sp = XMLsposti.parse(in);System.out.println("Sending message from " +

sp.lähettäjä.email +"to mailserver at " + args[0]);Socket soc =new Socket(args[0], ViestiPalvelin.VIESTIPORTTI);OutputStream os = soc.getOutputStream();XMLsposti.unparse(sp, os);os.flush(); os.close(); soc.close();

} // main} // class Viestittaja

Page 24: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

88 LUKU 8. VERKKOPROTOKOLLAT JA XML

Esimerkki 8.5 Lähetettävän viestin käsittely: XML-muotoinen sähköposti XMLsposti.java 1/3.

import org.apache.xerces.parsers.DOMParser;import org.apache.xerces.dom.DocumentImpl;import org.apache.xml.serialize. ∗;import org.xml.sax.InputSource;import org.w3c.dom. ∗;import java.io. ∗;import java.util. ∗;public classXMLsposti {

private static final String SPOSTI ="sposti" ;private static final String LÄHETTÄJÄ = "lahettaja" ;private static final String EMAIL = "email" ;private static final String NIMI = "nimi" ;private static final String VASTAANOTTAJAT = "vastaanottajat" ;private static final String VASTAANOTTAJA = "vastaanottaja" ;private static final String OTSIKKO ="otsikko" ;private static final String RUNKO ="runko" ;private static final String KAPPALE ="kappale" ;

public static Sposti parse(InputStream xmlIn)throws Exception {DOMParser parser =newDOMParser();parser.parse(new InputSource(new InputStreamReader(xmlIn)));Document doc = parser.getDocument();// Navigoidaan dokumenttia.Element root = doc.getDocumentElement();if (!root.getNodeName().equals(SPOSTI))

throw new Exception("Uloimman alkion tulee olla " + SPOSTI);Node ch = root.getFirstChild();

Lahettaja lähettäjä =null ;Vector vastaanottajat=new Vector();String aihe =null ;Vector kappaleet =new Vector();

ch = seekFor(ch, Node.ELEMENT_NODE);while (ch 6= null ) {

String n = ch.getNodeName();if (n.equals(LÄHETTÄJÄ)) lähettäjä = parseLähettäjä(ch);else if (n.equals(VASTAANOTTAJAT)) vastaanottajat = parseVastaanottajat(ch);else if (n.equals(OTSIKKO)) aihe = parseOtsikko(ch);else if (n.equals(RUNKO)) kappaleet = parseRunko(ch);// else throw new Exception("Outo elementti: "+ n);ch = seekFor(ch.getNextSibling(), Node.ELEMENT_NODE);

} // while

// Tuloksen muodostusint vnum = vastaanottajat.size();Vastaanottaja[] va =new Vastaanottaja[vnum];for (int i=0; i<vnum; i++) va[i] = (Vastaanottaja)vastaanottajat.elementAt(i);int knum = kappaleet.size();String[] ka =new String[knum];for (int i=0; i<knum; i++) ka[i] = (String)kappaleet.elementAt(i);Sposti sp =new Sposti();sp.lähettäjä = lähettäjä; sp.otsikko = aihe; sp.kappaleet= ka; sp.vastaanottajat= va;return sp;

} // unparse

private static Node seekFor(Node n,short t) {while ((n 6= null ) && (n.getNodeType()6= t))

n = n.getNextSibling();return n;

} // seekFor

private static String parseOtsikko(Node n) {return n.getFirstChild().getNodeValue(); }

... jatkuu

Page 25: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

8.5. XML JA JAVA 89

Esimerkki 8.5. Luokka XMLsposti (jatkoa 2/3).

... jatkoa

private static Lahettaja parseLähettäjä(Node n)throws Exception {Node child = seekFor(n.getFirstChild(), Node.ELEMENT_NODE);String email, nimi;if (child == null ) throw new Exception("Lähettäjällä ei osia." );if (!child.getNodeName().equals(EMAIL))

throw new Exception("Lähettäjän ensimmäinen osa tulee olla "+ EMAIL + "se oli " + child.getNodeName());

email = child.getFirstChild().getNodeValue();child = seekFor(child.getNextSibling(),Node.ELEMENT_NODE);if (child == null ) nimi = null ;else{

if (!child.getNodeName().equals(NIMI))throw new Exception("Lähettäjän toinen elementti on " + NIMI);

nimi = child.getFirstChild().getNodeValue();child = seekFor(child.getNextSibling(), Node.ELEMENT_NODE);if (child 6= null ) throw new Exception("Lähettäjässä kolmas elementti." );

}Lahettaja l =new Lahettaja();l.email = email; l. nimi = nimi;return l;

} // parseLähettäjä

private static Vector parseVastaanottajat(Node n)throws Exception {Node child = seekFor(n.getFirstChild(), Node.ELEMENT_NODE);if (child == null ) throw new Exception("Ei vastaanottaja-elementtejä." );Vector vec =new Vector();while (child 6= null ) {

if (!child.getNodeName().equals(VASTAANOTTAJA))throw new Exception("Vieras elementti: " + child.getNodeName());

vec.add(parseVastaanottaja(child));child = seekFor(child.getNextSibling(), Node.ELEMENT_NODE);

} // whilereturn vec;

} // parseVastaanottajat

private static Vastaanottaja parseVastaanottaja(Node n)throws Exception {Node child = seekFor(n.getFirstChild(), Node.ELEMENT_NODE);String email =null , nimi = null ;if (child == null ) throw new Exception("Vastaanottaja: email tai nimi." );String nn = child.getNodeName();if (nn.equals(EMAIL)) email = child.getFirstChild().getNodeValue();else if(nn.equals(NIMI)) nimi = child.getFirstChild().getNodeValue();else throw newException("Vastaanottajassa vieras elementti: " + nn);Vastaanottaja v =new Vastaanottaja();v.email = email; v.nimi = nimi;return v;

} // parseVastaanottaja

private static Vector parseRunko(Node n)throws Exception {if (!n.getNodeName().equals(RUNKO))

throw new Exception(RUNKO +":a odotettiin." );Node child = seekFor(n.getFirstChild(), Node.ELEMENT_NODE);Vector vec =new Vector();while (child 6= null ) {

if (!child.getNodeName().equals(KAPPALE))throw new Exception("Odotettiin elementtiä: " + KAPPALE);

vec.add(child.getFirstChild().getNodeValue());child = seekFor(child.getNextSibling(), Node.ELEMENT_NODE);

} // whilereturn vec;

} // parseRunko

... jatkuu

Page 26: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

90 LUKU 8. VERKKOPROTOKOLLAT JA XML

Esimerkki 8.5. Luokka XMLsposti (jatkoa 3/3).

... jatkuu

public static void unparse(Sposti sp, OutputStream xmlOut)throws Exception {// Tehdään juurisolmu+ muut solmut.Document doc =new DocumentImpl();Element rootElement = doc.createElement(SPOSTI);doc.appendChild(rootElement);Element lähettäjä = doc.createElement(LÄHETTÄJÄ);rootElement.appendChild(lähettäjä);Element vastaanottajat = doc.createElement(VASTAANOTTAJAT);rootElement.appendChild(vastaanottajat);Element otsikko = doc.createElement(OTSIKKO);rootElement.appendChild(otsikko);Element runko = doc.createElement(RUNKO);rootElement.appendChild(runko);// lähettäjäElement email = doc.createElement(EMAIL);lähettäjä.appendChild(email);email.appendChild(doc.createTextNode(sp.lähettäjä.email));Element nimi = doc.createElement(NIMI);lähettäjä.appendChild(nimi);nimi.appendChild(doc.createTextNode(sp.lähettäjä.nimi));// Vastaanottajatfor (int i=0; i<sp.vastaanottajat.length; i++) {

Vastaanottaja v = sp.vastaanottajat[i];Element e;if (v.email ==null ) {

e = doc.createElement(NIMI); e.appendChild(doc.createTextNode(v.nimi));}else{

e = doc.createElement(EMAIL); e.appendChild(doc.createTextNode(v.email));}Element e1 = doc.createElement(VASTAANOTTAJA);e1.appendChild(e);vastaanottajat.appendChild(e1);

} // for// Otsikkootsikko.appendChild(doc.createTextNode(sp.otsikko));// Runkofor (int i=0; i<sp.kappaleet.length; i++) {

Element e = doc.createElement(KAPPALE);e.appendChild(doc.createTextNode(sp.kappaleet[i]));runko.appendChild(e);

} // for// Puretaan tiedostoon.OutputFormat of =new OutputFormat(Method.XML,"utf-8" , false);XMLSerializer unparser =new XMLSerializer(xmlOut, of);unparser.asDOMSerializer();unparser.serialize(doc.getDocumentElement());

} // unparse

} // XMLsposti

classSposti {public Lahettaja lähettäjä;public Vastaanottaja[] vastaanottajat;public String otsikko;public String[] kappaleet;

} // Sposti

classLahettaja {public String email;public String nimi;

} // Lahettaja

classVastaanottaja {// Toinen aina null.public String email;public String nimi;

} // Vastaanottaja

Page 27: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

Luku 9

WWW-tekniikoista – old content

- rather old content

Servletti(engl. servlet) elipalvelinsovelmaon Java-kielinen olio, joka toimii WWW-palvelimenyhteydessä olevassa virtuaalikoneessa. Kaikkiin WWW-palvelimiin ei kuitenkaan ole upotettu virtu-aalikonetta, joten servlettejäkään ei voida suorittaa kaikkien WWW-palvelimien yhteydessä.

Seuraavaksi luvussa 9.1 kerrotaan servlettien taustasta,roolista ja yleisestä toimintaideasta. Lu-vussa 9.2 kerrotaan mahdollisuudesta määritellä HTML-kielisille WWW-sivuille lomakkeita, joidenavulla voidaan kutsua mm. servlettejä toimittaen niille samalla käyttäjän antamia arvoja. Tämän jäl-keen luvussa 9.3 tehdään katsaus servletteihin liittyviinluokkiin (mm. Servlet, HttpServlet, Http-ServletRequest, HttpServletResponse ja Cookie) ja niiden ominaisuuksiin. Servletteihin liittyvätluokat ovat paketeissajavax.servlet ja javax.servlet.http . Luvussa 9.4 esitetään tämänjälkeen kolme esimerkkiä palvelinsovelmien käytöstä. Loppukommentteja esitetään luvussa 9.5.

Servlettejä on käsitelty monissa kirjoissa, mutta useimmissa käsittely on pinnallista tai puutteel-lista. Tätä kirjoitettaessa paras kirja lienee edelleen “Java Servlet Programming”, Jason Hunter &William Crawford, 1998. Kyseinen kirja käsittelee jopa tiedostojen siirtämistä HTTP-protokollallaservlettioliolle.

9.1 Johdanto

Servletti eli palvelinsovelma on siis WWW-palvelimessa suoritettavaksi tarkoitettu (tietynlainen) Java-ohjelma. Servletti — kuten nimikin antaa ymmärtää — on tietyssä mielessä samanlainen kuin applet-tikin. Servlettiin ei appletin tapaan liity ’main’-metodia, mutta appleteista poiketen sillä ei voi ollaedes graafista käyttöliittymää. Servleteillä on hyvin tarkkaan määrätty rooli WWW-palvelimien yh-teydessä:niiden tehtävänä on dynaamisesti generoida WWW-sivuja.

Kaikki palvelimet eivät tue servlettejä. Itse asiassa servletit eivät ole edes osa JDK:ta (ei edesversiossa 1.4), vaan ne on itse asennettava kääntäjän (ja mahdollisesti WWW-palvelimen) yhteyteen.Sun on tehnyt servleteistä JSDK-kokonaisuuden, jonka voi asentaa JDK:n yhteyteen ja jonka mukanatulee jopa pienimuotoinen servlettejä tukeva WWW-palvelin.

Servlettien käyttämiseen liittyvät asiat ovat valitettavasti hieman WWW-palvelinkohtaisia asioi-ta. Servlettejä suoritetaan palvelimen oikeuksilla. Servletti voidaan luoda uudelleen jokaisen WWW-palvelimeen kohdistuvan servletin kutsun seurauksena, mutta yleensä servletit ovat luonnin jälkeenpysyvä osa palvelinta. Tämä tarkoittaa, että servletit muistavat tilansa kutsukerrasta toiseen — vaik-ka kutsuva taho onkin palvelimen sisällä olevan virtuaalikoneen ulkopuolella. Tällainen ominaisuus

91

Page 28: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

92 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

on erittäin hyödyllinen raskaissa sovelluksissa — servletti voi esimerkiksi käsitellä tietokantaa niin,että tietokantayhteyttä pidetään koko ajan auki. Palvelinkohtainen asia on myös servlettien luonti jaalustus — yleensä luonti tapahtuu sellaisella konstruktorilla, johon ei liity parametrejä ja luomisenjälkeen niitä käyttävä taho kutsuu niiden init()-metodia (parametrien määräämistapa on palvelinkoh-tainen asia).

WWW-palvelimen tehtävänä on välittää HTML-sivuja palvelinta käyttäville WWW-selaimille.HTML-sivujen ideahan, että ne ovat tekstimuotoisia sisältäen muotoilukomentoja ja esim. viittauk-sia muihin dokumentteihin. Viittaukset muihin dokumentteihin ovat johonkin palvelimeen kohdistu-via URL-osoitteita — kuljettaessa linkkiä pitkin kyseinenURL-välitetään URL:ssä mainitulle pal-velimelle ja WWW-palvelimen tapauksessa palvelin lähettää selaimelle takaisin HTML-sivun. Tällai-nen dokumenttien noutaminen tapahtuu HTTP-protokollallakäyttäen GET, POST, PUT tai muutamaamuuta komentoa. Huomaa, että HTTP-protokolla on yhteydetön — tässä mielessä on merkittävää, ettäservletit ovat pysyviä olioita. Toinen tärkeä huomio tässäyhteydessä on, että nykyään WWW-selaimeteivät ole passiivisten HTML-sivujen varastoja, vaan sivuja usein tuotetaan eri menetelmillä “lennos-ta”, dynaamisesti. Servlettien idea on juuridynaamisessa WWW-sivujen generoinnissa. Kuvassa 9.1havainnollistetaan servlettien toimintaympäristöä.

www−selain

www−palvelin kone

www−palvelin prosessi

servletti−olioita

verkkoyhteys

POST−komento

doPost()

HTML−sivu

GET−komento

HTML−sivu

doGet()

Kuva 9.1: Palvelinsovelmien suorittaminen.

Toinen servlettihin liittyvä idea on, että sivujen tuottamiseen voi liittyä “raskasta” laskentaa, jokatällä tavalla annetaan palvelimen tehtäväksi. Servletit ovat omimmillaan ns. kolmitasoarkkitehtuurien(3-tier) toteuttamisen yhteydessä: servletit ovat välitaso selaimen ja tietokannan välissä. Servletit onosin tehty korvaamaan ns. CGI-ohjelmointi.

Koska servlettejä kutsutaan “HTML-sivuilta WWW-selaimen” toimesta, niin herää kysymyksiä:(1) miten kutsun yhteydessä voidaan välittää tietoja ja (2)voiko servletti toimia yhteen WWW-selaimessa suoritettavan appletin kanssa? Eräs tapa välittää tietoa WWW-palvelimelle ja sitä kaut-ta servleteille ovat HTML-kielen FORM-määritykset, eli ns. lomakkeet. Näitä käsitellään tarkemminkohdassa 9.2. Idea on kuitenkin se, että voidaan antaa käyttäjän täyttää joitakin lomakkeen kohtia jasamalla määritellä, mitä URL:ää “kutsutaan” kun lomake on “täytetty”. Kutsuminen tarkoittaa mm.HTTP-protokollan mukaisen GET- tai POST-komennon lähettämistä — lomakkeessa täytetyt tiedotkoodautuvat automaattisesti tällaisen viestin yhteyteenja ne voidaan servletissä saada helposti selvil-

Page 29: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

9.2. LOMAKKEISTA 93

le.Toisen kysymyksen suhteen tilanne on valitettavasti sellainen, ettäservlettejä ja appletteja ei ole

tehty kommunikoimaan keskenään! Perusajatus on, että servlettiä kutsutaan HTTP-protokollaa käyt-täen.Voidaantoimia niin, että appletti avaa HTTP-yhteyden WWW-palvelimeen (ja jäsentää tuloksenvastauksena saamastaa HTML-sivusta), mutta tuolloin appletti tavallaan itse toimii selaimena selai-men sisällä — vaikkakin mahdollista, niin kovin järkevää tällainen toiminta ei ole.

Itse asiassa servletin ja appletin välille on mahdollista luoda myös soketti- ja/tai RMI-yhteys, mut-ta tämä ei ole kovin luonnollista ajatellen servlettien toimintaympäristöä. Tuolloin servlettejä käytet-täisiin ohi niiden normaalin rajapinnan. Soketti- ja RMI-yhteyksiä ei käsitellä tässä yhteydessä.

9.2 Lomakkeista

HTML-kielen lomakkeet1 (engl. forms) ovat tapa välittää tietoa servleteille HTTP-protokollan yli.Servlettejä kutsuvat lomakkeet näyttävät HTML-koodissa seuraavalta:

<FORM METHOD="POST" ACTION="http://kohdekone/servlets /OmaServletti">

... määrityksiä

</FORM>

METHOD-kohdassa määritellään käytettävä HTTP-protokollan komento. Arvo ’POST’ ei ole ainoamahdollinen — itse asiassa ’GET’:n merkitys on sama kuin ’POST’:kin. Niiden ero on lähinnä tekni-nen ja syy osittain vanhentunut — ’GET’:n yhteydessä on aikoinaan ajateltu lähetettävän vain hyvinvähän muuta tietoa ja ’POST’:n yhteydessä voidaan lähettäävaikka tiedostoja asiakkaalta WWW-palvelimelle.

9.2.1 FORM:n määrityksistä

FORM-määrityksen sisällä on lisää määrityksiä, joiden avulla voidaan muodostaa HTML-sivulle jotutuksi tulleita yksinkertaisia GUI-komponentteja. Näistä määrityksistä tehdään seuraavaksi selkoa.Tarkemmin asiat on määritelty HTML 4.01:n määrittelyssä (www.w3c.org).

Kenttä

Kenttä on määre, joka on muotoa

<INPUT TYPE="tyyppi" NAME="nimi" VALUE="arvo">

Idea on, että määritellään “nimi”-niminen resurssi, jollaon alkuarvo “arvo”. Edellisessä tyypillä voiolla useita arvoja ja sen mukaan määräytyy WWW-sivulle syntyvä GUI-komponentti. Komponentintyypin mukaan määräytyy tapa, jolla arvo voi muuttua. Mahdollisia arvoja tyypille ovat

TYPE="text" — Esittää tekstikenttäkomponenttia, johon voidaan kirjoittaa tekstiä.

1Ks. http://www.w3c.org/TR/html4/interact/forms.html .

Page 30: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

94 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

TYPE="radio" — Esittää radionappulaa ja NAME:n arvo kertoo ryhmän. VALUE:lla voidaan vä-littää tieto siitä, mikä saman ryhmän radionappuloista painettu pohjaan.

TYPE="checkbox" — Esittää valintaruutua. Toiminta on radionappuloiden tapaista, mutta NAME:avastaava arvo esiintyy resurssina vain jos jokin kyseisen NAME-arvon omaavista valintaruu-duista on painettu pohjaan. Resurssin VALUE:n arvona ovat kaikkien niiden valintaruutujenVALUE-osien arvot, joita vastaava kyseisen niminen valintaruutu on painettu pohjaan.

TYPE="submit" — Erityinen nappula, jota painamalla FORM:n ACTION osa käynnistyy. VALUE-osalla voidaan asettaa nappulan teksti (oletusarvoisesti“submit”).

TYPE="reset" — Tämä muodostaa myös nappulan kuten ’submit’, mutta tarkoituksena on palauttaapainamisen seurauksena kaikkien kenttien arvo niiden alkuarvoiksi.

TYPE="image" — Kuten ’submit’, mutta nappulan sisältönä kuva.

TYPE="password" — Kuten “text”, mutta esittää salasanakenttää.

TYPE="file" — Esittää tiedoston nimen valintatyökalua. Valittava tiedosto lähetetään HTTP-komennonmukana MIME-koodattuna, jos lomakkeen otsikossa on on seuraava määritys: ENCTYPE="multipart/mime".

TYPE="hidden" — Piilokenttä vakioarvon välittämiseksi.

Esimerkiksi seuraava FORM-määrittely

<FORM action="http://koneen-nimi/AddUserServlet" meth od="post"><P> First name: <INPUT type="text" name="firstname"><BR>

Last name: <INPUT type="text" name="lastname"><BR>email: <INPUT type="text" name="email"><BR>

<INPUT type="radio" name="sex" value="Male"> Male<BR><INPUT type="radio" name="sex" value="Female"> Female<B R><INPUT type="submit" value="Send"> <INPUT type="reset">

</P></FORM>

näyttää selaimessa seuraavalta

Page 31: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

9.3. SERVLETTIEN TEKEMISESSÄ TARVITTAVIA LUOKKIA 95

Valintalista

Valintalista on myös jo tuttu GUI-komponentti. HTML:n FORM:ien yhteydessä se määritellään seu-raavasti

<SELECT NAME="nimi"><OPTION>Vaihtoehto nro1</OPTION><OPTION SELECTED>Vaihtoehto nro2</OPTION><OPTION>Vaihtoehto ...</OPTION>

</SELECT>

Eli, kutakin vaihtoehtoa kohti määritellään <OPTION>-rivi. NAME on samassa roolissa kuin kentänyhteydessä. Tavallaan tämä on kenttä, jonka arvo valitaan annetusta joukosta. ’SELECTED’ tarkoittaa,että yksi on jo valittuna2.

Tekstialue

Tekstikentän yleistys, tekstialue, on myös osana FORM:a. Sen määrittelyn muoto on pelkistetysti allaolevan muotoinen. ’ROWS’ ja ’COLS’ saavat arvokseen positiivisia kokonaislukuja.

<TEXTAREA NAME="nimi" ROWS="rivit" COLS="sarakkeet">Tässä voi antaa tekstin oletusarvon.

</TEXTAREA>

Muita

Itse asiassa muitakin määreitä on — mm. nappula, mutta niistä ei tehdä selkoa tässä yhteydessä.

9.3 Servlettien tekemisessä tarvittavia luokkia

Servlettien tekemissä tarvittavat luokat eivät ole osa JDK:ta (ei edes versiossa 1.4), vaan ne löytyvätmm. Sunin JSDK-paketista3. JSDK koostuu kahdesta paketista:javax.servlet ja javax.servlet.http .Niissä on n. 40 luokkaa tai rajapintaa. Olennaisimmat näistä ja niiden väliset perimyssuhteet on esi-tetty kuvassa 9.2 (italics-tyyliset ovat rajapintoja).

LuokkaServlet on rajapinta, jonka toteuttavat abstraktit luokatGenericServlet ja HttpServlet.Servlet-luokalla ei ole juurikaan metodeja — erityisesti ei yhtäänsuoraan HTTP:hen liittyvää me-todia; ks. taulukko 9.1. LuokallaGenericServlet on jo aika runsaasti metodeja. Ne liittyvät lähespoikkeuksetta servlettiä kutsuvan tahon tietojen havainnointiin ja ylipäänsä “hallinnollisiin” asioihin.Tässäkään luokassa ei ole mitään HTTP:hen liittyvää — luokan GenericServlet metodeja ei tässäyhteydessä esitetä.

Taulukkoon 9.2 on kerätty joitakin luokanHttpServlet metodeja — itse asiassa kaikki muut hyö-dylliset metodit on peritty luokanGenericServlet kautta. Jokaista HTTP-protokollan mukaista ko-mentoa kohti on luokassa metodi. Metodien muoto on täsmälleen sama — metodien semantiikastavastaa niiden toteuttaja. Oletusarvoisesti metodit eivättee mitään. Huomaa, että periaatteessa voisitoimia niin, että lomakkeessa kutsuu DELETE-komennolla servlettiä, mutta (tiedoston) tuhoamisensijaan voi vapaasti määritellä, miten servlettiolio reagoi kyseiseen komentoon. Metodien semantiikantulisi kuitenkin olla HTTP-protokollan komentojen semantiikan mukaista.

2Itse asiassa useitakin voidaan valita; katso tarkempi SELECT:n kuvaus HTML 4.01:n määrittelystä.3Ks. http://java.sun.com/products/servlet/ .

Page 32: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

96 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

GenericServlet

Cookie

HttpServletResponse

ServletResponse Servlet

HttpServlet

ServletRequest

HttpServletRequest

Kuva 9.2: Muutamia servletteihin liittyviä luokkia ja niiden väliset perimyssuhteet.

void init(ServletConfig c) — Servlettiolion alustus; kutsutaan vain kerran;c tulee palvelimelta.void service(ServletRequest rq, ServletResponse rs) — Servletin kutsu ohjataan ensin tähän me-

todiin.

Taulukko 9.1: Joitakin rajapinnanServlet metodeja.

Seuraavaksi esittelyvuorossa on rajapintaHttpServletRequest (taulukko 9.3). Sillä on varsinrunsaasti havainnointimetodeja, joiden kautta voidaan havainnoida sitä, mitä tietoa HTTP-komennonyhteydessä on servlettioliolle välitetty.

RajapinnanHttpServletResponse metodeita on lueteltu taulukossa 9.4. Lähinnä hyödyllisiäovatmuodostettavan sivun tyypin asettaminen, piparien liittäminen palautettavaan sivuun ja ’getWriter’,jolla otetaan käyttöön tiedostovirta, jonne muodostettava sivu tulee kirjoittaa.

Edellisten lisäksi hyödyllinen luokka on myösCookie (taulukko 9.5), jolla on lähinnä konstrukto-ri sekä metodeja pipariin (engl. Cookie) liittyvien ominaisuuksien asettamiseksi ja havainnoimiseksi.Piparin avulla palvelin voi tallettaa asiakkaaseen (siis asiakkaana olevan selainohjelman yhteyteen)tietoa itsestään ja yhteydestään tähän asiakkaaseen. Piparit ovat erittäin hyödyllisiä servlettien yhtey-dessä —piparien tarkoitus on tarjota palvelimelle selaimesta “muistipaikka”, jonne se voi taltioidahaluamaansa tietoa. Piparien olennaiset ominaisuudet on selitetty taulukon 9.5 yhteydessä.

9.4 Esimerkkejä

9.4.1 Esimerkki HelloServlet

Esimerkissä 9.1 on esitetty HTML-tiedosto, jolla on vain yksi nappula. Nappulan painamisen seurauk-sena kutsutaan (bg.cs.utu.fi-koneen) servlettiä ’HelloServlet’ (ja esitetään tuloksena saatava HTML-sivu).

Page 33: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

9.4. ESIMERKKEJÄ 97

protected void doDelete(HttpServletRequest rq, HttpServletResponse rs) — Käsittelee HTTP-protokollan mukaisen DELETE-komennon.

protected void doGet(HttpServletRequest rq, HttpServletResponse rs) — Käsittelee HTTP-protokollan mukaisen GET-komennon.

protected void doHead(HttpServletRequest rq, HttpServletResponse rs) — Käsittelee HTTP-protokollan mukaisen HEAD-komennon.

protected void doOptions(HttpServletRequest rq, HttpServletResponse rs) — KäsitteleeHTTP-protokollan mukaisen OPTIONS-komennon.

protected void doPost(HttpServletRequest rq, HttpServletResponse rs) — Käsittelee HTTP-protokollan mukaisen POST-komennon.

protected void doPut(HttpServletRequest rq, HttpServletResponse rs) — Käsittelee HTTP-protokollan mukaisen PUT-komennon.

protected void doTrace(HttpServletRequest rq, HttpServletResponse rs) — Käsittelee HTTP-protokollan mukaisen TRACE-komennon.

protected void service(HttpServletRequest rq, HttpServletResponse rs) — Tätä metodia varsi-naisesti kutsutaan WWW-selaimen toimesta; komennon mukaan tämä kutsuu edellisiä.

Taulukko 9.2: Joitakin luokanHttpServlet metodeja.

String getParameter(String p) — Palauttaa lomakkeelta lähetetyn parametrinp arvon.Enumeration getParameterNames() — Kaikkien komennon yhteydessä välittyjen parametrien ni-

met.Cookie[] getCookies() — Palauttaa sisääntulevat piparit!ServletInputStream getInputStream() — Binäärinen lukuvirta lähetettyyn dataan.BufferedReader getReader() — Sama tekstipohjaisena.String getContentType() — Kertoo missä MIME-muodossa komennon yhteydessä välitettävä data

tulee.int getContentLength() — Datan pituus.

⋆ ’getRemoteHost’, getRemoteAddr’, ’getRemoteUser’, ’getMethod’, ’getServerName’, ’getSer-verPort’, . . .

Taulukko 9.3: Joitakin rajapinnanHttpServletRequest metodeja.

Esimerkki 9.1 HelloServlet.html — HTML-tiedosto, joka käynnistää yksinkertaisen servletin.

<html><head><title> HelloServlet </title></head><body>

<h2> HelloServlet:n käynnistävä sivu </h2>

<form method="GET" action="http://bg.cs.utu.fi:8080/s ervlet/HelloServlet"><input type=submit value="Push">

</form></body></html>

Page 34: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

98 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

ServletOutputStream getOutputStream() — Palauttaa binäärisen lähtevän virran.PrintWriter getWriter() — Sama merkkipohjaisena; tällä toteutetaan sivujen kirjoittaminen.void setContentType(String c) — Asettaa ulosmenevän sivun koodaukseksic:n; esimerkiksi

text/html .void sendError(int code,String msg) — Palauttaa virheilmoitussivun takaisin virhekoodilla code ja

viestillä msg.void addCookie(Cookie c) — Asettaa piparin lähtevään virtaan.

Taulukko 9.4: Joitakin rajapinnanHttpServletResponse metodeja.

Kuva 9.3: HelloServlet.html:n suorittaminen.

Kuvassa 9.3 on esitetty tilanne, jossa selaimella suoritetaan lomakkeen sisältävää HTML-tiedostoaHelloServlet.html. Kuvassa 9.4 on vastaavasti tilanne, jossa HTML-sivun ’push’-nappulan painamisenseurauksena on suoritettu esimerkissä 9.2 oleva servletti. Servletti on tuottanut kuvassa olevan HTML-sivun.

Kuva 9.4: Tilanne HelloServlet.html:n ’push’-nappulan painamisen jälkeen.

Page 35: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

9.4. ESIMERKKEJÄ 99

Cookie(String name,String value) — Konstruktori, joka luo piparin, jolla niminame ja arvovalue

(RFC 2109).boolean getSecure() — Onko turvallinen yhteys käytössä? HTTPS tai SSL.

⋆ Voidaan asettaa (setXXX-metodi) ja havainnoida (getXXX-metodi) useita ominaisuuksia:

• kommentti(Comment) — mikä on tämän piparin merkitys;

• voimassaoloaika(MaxAge) — selain ei lähetä piparia enää takaisin, jos voimassaoloaikaon mennyt umpeen;

• URL-polku (Path) — määrittää polun palvelimen sisältä; aina kun selain pyytää jotainsivua, jonka etuliitteenä on tämä polku, lähetetään tämä pipari komennon mukana; ole-tusarvoisesti piparit liittyvät vain siihen sivuun, jonkayhteydessä ne ensimmäisen kerranvälitettiin selaimelle;

• domain-nimi(Domain) — edellisen laajennos, pipari voidaan välittää nyt URL:ään liitty-vän domain nimen mukaan;

• arvo (Value) — merkkijono, joka sisältää sen datan, jonka palvelin haluaa piparin mukanataltioida selaimeen;

• nimi (Name) — piparin nimi;

• versionumero(Version) — tuetaan versioita 0 & 1 (RFC 2109); ja

• turvallisuus(Secure) — onko pipari välitetty turvallisen yhteyden yli.

Taulukko 9.5: Joitakin luokanCookie metodeja.

Esimerkki 9.2 HelloServlet.java — yksinkertainen servlettiohjelma.

import javax.servlet.∗;import javax.servlet.http.∗;import java.io.∗;

public classHelloServletextendsHttpServlet {public void doGet(HttpServletRequest rq,

HttpServletResponse rs)throws IOException, ServletException {rs.setContentType("text/html" );PrintWriter out = rs.getWriter();out.println(" <html >" );out.println(" <title > Hello there! </title >" );out.println(" <body >" );out.println(" <IMG SRC=http://www2.cs.utu.fi/icons/slidbar.gif ALT =>" );out.println(" <h1> Tervehdys! </h1 >" );out.println(" <IMG SRC=http://www2.cs.utu.fi/icons/slidbar.gif ALT =>" );out.println(" </body ></html >" );

} // doGet} // class HelloServlet

Page 36: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

100 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

Esimerkissä 9.2 oleva ohjelma periiHttpServlet luokalta kaikkiin HTTP-protokollan komentoi-hin reagoivat metodit, mutta antaa uuden toteutuksen vain yhdelle niistä: ’doGet’:lle. Huomaa, mitenmetodin toteutuksessa ei välitetä lainkaan siitä, mitä servlettioliolle annetaanHttpServletRequest-tyyppisen parametrin kautta, vaan servletti vain vakiomuotoisesti kirjoittaa vastauksena HTML-sivunServletResponse-tyyppiseen parametriin liittyvän tiedostovirran kautta.

9.4.2 Esimerkki hieman monimutkaisemmasta servletistä

Esimerkissä 9.3 on esitetty HTML-tiedosto, jossa käytetään useita kohdassa 9.2 kuvattuja lomakkeenkomponentteja.

Page 37: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

9.4. ESIMERKKEJÄ 101

Esimerkki 9.3 LomakeServlet.html — HTML-tiedosto, joka käynnistää lomakkeen tiedot vas-taanottavan servletin.

<html> <head> <title> Lomakkeen välittämistä ... </title> </head>

<body>

<p> Täytä seuraavat ja paina lopuksi ’lähetä’. </p>

<form method=POST ENCTYPE="multipart/mime"ACTION=http://bg.cs.utu.fi:8080/servlet/LomakeServl et>

<input type=hidden name="PiiloArvo" value="Oletusarvo" >

<p> Nimi: <input type=text name="Kentta1" value=""> </p>

<p> Osoite: <input type=text name="Kentta2" value="Osoit e"> </p>

<p> Salasana: <input type=password name="Kentta3" value= ""> </p>

<p> Opinnot aloitettu:<select name="Opinnot">

<option> muu </option><option selected> 1999 </option><option> 2000 </option><option> 2001 </option>

</select>

<p> Valitse jokin:<input type=radio name="Valinta" value="1999"><input type=radio name="Valinta" value="2000"><input type=radio name="Valinta" value="2001"></p>

<p> Valitse tiedosto: <input type=file name="Tiedosto" ac cept="html"> </p>

<p> <input type=reset value="Resetoi"> <input type=submi t value="Lähetä"> </p></form></body></html>

Kuvassa 9.5 on esitetty tilanne, jossa selaimella suoritetaan LomakeServlet.html -tiedostoa. Ku-vassa 9.6 on vastaavasti tilanne, jossa HTML-sivun ’lähetä’-nappulan painamisen seurauksena onsuoritettu esimerkissä 9.4 oleva servletti. Servletti on tuottanut kuvassa olevan HTML-sivun.

Page 38: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

102 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

Kuva 9.5: LomakeServlet.html:n suorittaminen.

Esimerkki 9.4 Servletti, joka vain selvittää, mitä parametrien kautta sille on lähetetty.

import javax.servlet.∗;import javax.servlet.http.∗;import java.io.∗;

public classLomakeServletextendsHttpServlet {public void doPost(HttpServletRequest rq,

HttpServletResponse rs)throws IOException, ServletException {String[] q = { "PiiloArvo" , "Kentta1" , "Kentta2" ,

"Kentta3" , "Opinnot" , "Valinta" , "Tiedosto" };rs.setContentType("text/html" );PrintWriter out = rs.getWriter();out.println(" <html >" );out.println(" <title > Vastaanotettiin seuraavaa </title >" );out.println(" <body >" );for (int i=0; i<q.length; i++) {

out.print(" <p> " + q[i] + " = " );out.print(rq.getParameter(q[i]));out.println(" </p >" );

}out.println(" </body ></html >" );

} // doPost} // class LomakeServlet

Esimerkin 9.4 ohjelma muodostaa myös HTML-sivun, mutta esimerkistä 9.2 poiketen käytetään

Page 39: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

9.5. LOPUKSI 103

Kuva 9.6: Tilanne LomakeServlet.html:n ’lähetä’-nappulan painamisen jälkeen.

hyväksiHttpServletRequest-tyyppisen parametrin kautta välitettyjen parametrien arvoja. Arvojensisältö vain tulostetaan sivun sisällöksi.

9.5 Lopuksi

Servletit ovat WWW-palvelimessa olevia olioita, joita voidaan HTTP-protokollaa käyttäen kutsua —ne säilyttävät tilansa kutsusta toiseen. Koska servlettiäkäytetään HTTP:n kautta, servlettien pääasial-linen toimintaidea on dynaaminen HTML-sivujen generointija toisaalta työn osittainen siirtäminenpalvelimelle.

Servlet–applet -keskustelu on periaatteessa mahdollinen, esimerkiksi soketeilla ja RMI:llä (käy-tetään säikeitä apuna), mutta sellainen keskustelu ohittaa HTTP-protokollan. Keskustelun saa tokimyös aikaan HTTP-protokollan avulla, mutta tuolloin appletti joutuu esimerkiksi jäsentämään tulok-sen servletin lähettämästä HTML-sivusta (hyvin epäluonnollista).

HTTP-protokollan yhteydettömyyteen saadaan ratkaisuja pipareista ja siitä, että servlettioliot säi-lyttävät tilansa (niin kauan kun WWW-palvelin on pystyssä). Piparit tuovat selkeästi erään ratkaisuuseiden samanaikaisten käyttäjien erotteluun servletin kannalta. Usein servlettien avulla halutaan tal-lettaa (lomakkeen kautta syötettyjä) tietoja tietokantaan tai vastaavasti lukea joitakin tietoja tietokan-nasta. Tähän tarkoitukseen servletit soveltuvat erittäinhyvin.

Eräs näppärä tapa toteuttaa sivusto servlettien avulla on olla kirjoittamatta lainkaan HTML-sivuja.HTML-sivut voidaan nimittäin koodata osaksi servlettiä. Voidaan toimia niin, että servletin ’doGet’-metodi palauttaa HTML-sivun, jossa on mukana lomake, joka kutsuu samaa servlettiä POST-menetelmällä,käyttäen siis sen ’doPost’-metodia.

Servletteihin liittyy läheisesti myös esimerkiksi JSP (Java Server Pages), mutta sitä ei tämä oppi-materiaalin puitteissa käsitellä. Lopuksi pitää hieman harmillisesti todeta, että vaikka HTML-sivujen

Page 40: RPC - utustaff.cs.utu.fi/opinnot/kurssit/HOJ-2012/moniste/hoj-L7...66 LUKU 7. RPC • (Stub = tynkä) 1. Kutsuva ohjelma kutsuu edustaproseduuria kuten muitakin paikallisia proseduureja

104 LUKU 9. WWW-TEKNIIKOISTA – OLD CONTENT

avulla on mahdollista lähettää tiedostoja MIME-koodatusti servlettioliolle, niin kyseisten tiedostojenjäsentämistä ei ole toteutettu juuri missään — erityisestiJavan luokkakirjastoista ei löydy tukea asialle(tämän luvun alussa mainitussa kirjassa tosin näytetään, miten se on mahdollista tehdä).