HOJ Protokollista & XML Ville Leppänen HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.1/66
Missä mennään... 1. Johdanto (1h) 2. Säikeet (2h) 3. Samanaikaisuudesta (2h) 4. Hajautetuista sovelluksista (1h) 5. Soketit (3h) 6. RMI ja J2EE (3h) 7. RPC (1h) 8. WWW-sovellustekniikoista ja XML + protokollat (2h) 9. Pilvialustat (4h) 10. Haja-aiheita (2h) 99. Kertausluento (2h) + 1h pelivaraa HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.2/66
Luennon rakenne Protokollista Yleistä Protokolla asiakkaan ja palvelimen kannalta; tilat Kuvaaminen, Muodostaminen Protokollasta luokiksi Viime aikaisia suuntauksia XML sopii mm. protokollan viestien esittämiseen Mikä XML on? Käsitteitä: XML, XSL, DTD, skeema,... XML:n käyttötilanteita, XML-esimerkkejä DOM ja SAX: XML-dokumentit Java-ohjelmissa. Esittäminen, jäsentäminen ja antijäsentäminen. Esimerkkejä. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.3/66
Protokollista Rajoitutaan viestipohjaisiin yhteydellisiin protokolliin. Taustaa; protokolla asiakkaan ja palvelimen kannalta; tilat Muodostaminen Kuvaaminen Protokollasta luokiksi HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.4/66
Protokollista: taustaa 1/2 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 viestien tarkka muoto sekä keskustelun etenemistavat. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.5/66
Protokollista: taustaa 2/2 Hajautetun sovelluksen voidaan ajatella olevan jossain tilassa. Viesti(e)n lähettämisen seurauksena sovellus siirtyy tilasta toiseen. Vuoropohjaisissa protokollissa usein vähän vaihtoehtoja seuraavalle viestille (& tilasiirtymälle). Keskustelevien osapuolten pitää mieltää hajautetun sovelluksen olevan jossain tilassa ja hyväksyä vain tilan kannalta lailliset viestit. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.6/66
Protokollista: 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 keskustelun muoto (viestejä). HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.7/66
Protokollista: viestien koodaus Binäärisessä muodossa, esim. kirjoitetaan olioita TCP-sokettien tiedostovirran päällä. Tekstimuodossa (perinteinen vaihtoehto): suunnitellaan itse viestien muoto ja koodaus. Moderni variaatio: esitetään viestit XML:llä. Kaikkien edellisten vaihtoehtojen yhteydessä on hyvinkin järkevää esittää viestit ohjelmassa erilaisilla Java-olioilla. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.8/66
Protokollista: kuvaaminen Muodostetaan sovellukselle tiloja. Tilat ovat hajautetun järjestelmän kokonaistiloja, mutta usein 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. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.9/66
Esimerkki: tilakaavio tee yhteys odot. yhteyd.otto yhteys tehty odotetaan autentikointia login ok kyselyjen palvelu logout lopetustila yhteys tehty login fail login login ok kyselyn tulos tee kysely logout logout ok close conn. close ok autentikointi kyselytila logout tehdään logout lopetustila HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.10/66
Tilakaavio asiakaan kannalta tee yhteys epäonnistunut login autentikointi epäonnistuva kysely onnistunut kysely onnistunut login kyselytila logout tehdään logout logout lopetustila yhteyden sulkeminen HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.11/66
Tilakaavio palvelimen kannalta odot. yhteyd.otto yhteys tehty odotetaan autentikointia login ok kyselyjen palvelu palvellaan kyselypyyntö logout lopetustila HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.12/66
Keskustelu sekvenssikaaviona : asiakas onnistunut : palvelin login autentikointi tila LOGIN viesti autentikointi tila kyselytila LOGINOK viesti kyselytila HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.13/66
Protokollista: luokiksi Perusajatus: Luetellaan kaikki järjestelmässä tarvittavat viestit ja tehdään jokaista vastaten yksi luokka. 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. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.14/66
Protokollista: esimerkki Pohditaan esimerkkiä, jossa henkilöiden tietoja haetaan palvelimelta. Ensin pitää onnistuneesti autentikoida. Sitten voidaan tehdä useita kyselyjä. Lopuksi suljetaan yhteys palvelimeen. Tarkoitus linkittää IT-laitoksen henkilötietokantaan. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.15/66
ITinfo: tilakaavio asiakkaasta kytkeytyminen laiton toimenpide autentikointitila epäonnistunut autentikointi logout login laiton toimenpide kyselytila logout kyselyn tekeminen lopetustila lopettaminen HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.16/66
Esimerkki: joitakin viestejä A P: Tee autentikointiyritys P A: Autentikointi onnistui P A: Autentikointi epäonnistui P A: Autentikointi suoritettu jo A P: Anna ilmoitetun henkilön tiedot P A: Palautetaan halutut tiedot P A: Kyseistä henkilöä ei ole A P: Sulje yhteys P A: Yhteys sulkeutuu Kustakin luokka + yliluokka XXX_App_Message. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.17/66
Luokka ITinfo_Message import org.w3c.dom. ; public abstract class ITinfo_Message { public abstract ITinfo_Message parse(document doc); public abstract void unparse(document doc); } // class ITinfo_Message HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.18/66
ITinfo_Login_Message 1/2 import org.w3c.dom. ; public class ITinfo_Login_Message extends ITinfo_Message { private String user; // tunnus private 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; } HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.19/66
ITinfo_Login_Message 2/2 public ITinfo_Message parse(document doc) { // jäsennetään DOM:sta ITinfo_Login_Message String p = ; String u = ; //... luetaan arvot u:lle ja p:lle return new ITinfo_Login_Message(u,p); } // parse public void unparse(document doc) { // muodostetaan rakenne tyhjään dokumenttiin... } // unparse } // class ITinfo_Login_Message HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.20/66
ITinfo_Login_Message XML:nä <?xml version="1.0" standalone="yes"?> <itinfo_message> <itinfo_login_message> <user> villep </user> <passwd> salainen </passwd> </itinfo_login_message> </itinfo_message> Mahdollisesti uloin kuori pois + pitäisi tehdä DTD-määrittely. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.21/66
Viime aikaisia suuntauksia Protokollaa ja ylipäänsä järjestelmän toimintaa suunniteltaessa olennaista päättää missä tilatietoa ylläpidetään. Perinteinen ratkaisu: pidetään tilatietoa sekä asiakkaissa että palvelimissa. Thin client: pidetään kaikki tieto palvelimessa. Rest = representational state transfer: pidetään kaikki tilatieto yhteydestä asiakkaassa. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.22/66
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. Perustuu web-sivun sisällön dynaamiseen muuttamiseen ilman sivun uudelleenlataamista. Esim. Vaadin (IT Mill Oy). Ohut asiakas -tekniikkaa täydentää pilvilaskenta. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.23/66
REST-tekniikka Palvelimella hajautetun järjestelmän tilatietoa, mutta kaikki asiakasyhteyteen liittyvä tieto asiakkaalla (toimitetaan pyyntöjen mukana palvelimelle). Asiakas-palvelin-suhde on tilaton: palvelin on aina levossa ja palvelee yksittäisen pyynnön kerrallaan. Tuloksiin voidaan soveltaa välimuistiin taltiointia. Muita periaatteita: layered design, uniform interfaces ja code-on-demand. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.24/66
Mikä XML on? Kehitetty alunperin tuomaan rakennetta WWW:n sisältöön, rakennetta HTML-sivujen latteuden tilalle. XML = extensible Markup Language. Johdettu yleisestä SGML:stä. XML on rakenteisen tiedon kuvauskieli. XML-dokumentti kuvaa yhden rakenteisen tietoalkion. XML pyrkii myös antamaan merkityksen kuvatulle tiedolle. XML on joukkotekniikkoja tiedon kuvaamiseksi, käsittelemiseksi ja esittämiseksi. XML on suunniteltu WWW:stä lähtöisin, mutta soveltuu muuallekin. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.25/66
XML: Mitä? Kuka? Koska? W3C:n (World Wide Web Consortium) kehittämä kieli mutta samalla joukko tekniikkoja. www.w3.org; n. 500 jäsenorganisaatiota; Tim Berners-Lee perusti 1994. (MIT, CERN, DARPA, EU, Nokia, HUT,... ) Kehitystyö alkoi 1990-luvun puolivälissä. XML 1.0 suositus, helmikuu 1998. (Sun, Microsoft, netscape, yliopistoihmisiä.) Nimiavaruudet, tyylitiedostot, ja 50+ muuta suositusta. W3C:llä useita työryhmiä XML:stä tälläkin hetkellä. XML 1.1 suositukseksi 4/2004 + paljon muuta. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.26/66
W3C: XML in 10 points 1. Tiedon strukturointi. Nykyään kaikkialla: tietokannan tietue, OO-kielen olio,... 2. XML-kieli HTML-kielen tapainen. 3. Tekstipohjainen kuvaus, ei tarkoitettu luettavaksi. 4. Havainnollisuus: Kuvauksia voi tehdä käsin; tiivistäminen. 5. Joukko teknologioita kuvauskielen lisäksi. 6. XML on melko uusi, SGML on ISO-standardi, 1980 alkupuoli. 7. XML: HTML XHTML. 8. XML-dokumentilla voi olla tyyppi; tyypin voi koostaa modulaarisesti. 9. XML toimii semattisen webin perustana. 10. XML on lisenssivapaa, alustariippumaton ja hyvin tuettu. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.27/66
XML:n käyttötilanteet XML-dokumenttien esittäminen (selain) XML-dokumenttien välittäminen XML-dokumenttien jäsentäminen XML-dokumenttien tuottaminen XML ja verkkoviestintä HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.28/66
Esittäminen WWW-selaimessa XML konversio ohjelma HTML + muuta (CSS) www selain XSL XML XML pohj. verkkoselain XSL XML-pohjaisia selaimia on jo aika HOJ, hyvin. c Ville Leppänen, IT, Turun yliopisto, 2012 p.29/66
XML-dokumenttien välittäminen sovellus A XML dokumentti sovellus B DTD XML toimii tiedon esitysmuodon standardina. Osapuolten pitää sopia dokumenttien muodosta ja merkityksestä; DTD-tiedostoja. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.30/66
XML-dokumenttien jäsentäminen sovellus XML dokumentti XML jäsentäjä XML olioita Useita jäsentäjiä (Java); Xerces. DOM, SAX, StAX: tapoja käydä läpi oliomuotoinen XML-dokumentti. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.31/66
XML-dokumenttien tuottaminen Useita tapoja. Käsin (ei suuressa mittakaavassa). Nykyään saatavilla runsaasti erilaisia XML-editoreja! Generoidaan tietokannan tietojen perusteella. Itsenäinen ohjelma, joka käyttäjä tietojen perusteella tekee XML-dokumentin (DOM). Tuotetaan XML-dokumentteja eri WWW-tekniikoiden yhteydessä.... HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.32/66
XML ja verkkoviestintä Liittyy dynaamiseen sisällön tuottamiseen kuten servletit, JSP, ASP, jne. XML:n rooli on tiedon sisällön esittämisessä ei niinkään ulkoasun esittämisessä (vaikka siihen toki panostettu myös). XML:n alkuperäinen tarkoitus ei ole ilmaista, mistä tieto koostetaan. XML ei ole verkkolomake, vaan pikemminkin verkkolomakkeen täyttämisen tulos. XML:llä voidaan esittää verkko-ohjelmien protokollan viestit! HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.33/66
Mitä XML:llä kuvataan? Esimerkki: HTML-dokumentilla on tagi-rakenne: <title> Sivun otsikko </title> <body> <h1> Pääotsikko </h1> Tekijä on <b>l. Auri</b>... <p>... </body> Ongelma: <b>... </b> -osassa olevan tiedon merkitys ei selvä dokumentin käsittelyn kannalta. XML-dokumenteilla myös hierarkinen tagi-rakenne, mutta tageilla semanttinen merkitys (vai onko?). HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.34/66
Esimerkki XML-dokumentista <?xml version="1.0" standalone="yes"?> <sahkoposti> <lahettaja> <email> Ville.Leppanen@it.utu.fi </email> <nimi> Ville Leppänen </nimi> </lahettaja> <vastaanottajat> <vastaanottaja <email> hannu@utu.fi </email> </vastaaottaja> <vastaaottaja> <email> heikki@utu.fi </email> </vastaaottaja> </vastaanottajat> <otsikko> Koeviesti </otsikko> <runko> <kappale> Heips! </kappale> <kappale> Olin muuten... </kappale> </runko </sahkoposti> HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.35/66
Esimerkki puurakenteena dokumentti sähköposti lähettäjä vastaaottajat otsikko runko email vastaanottaja kappale kappale nimi email Heips! Olin... Ville.L... hannu@.. Ville heikki@.. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.36/66
XML-dokumentin luonnehdintaa 1/3 XML-dokumentti oliokielen olio Pascalin tietue relaatiotietokannan tietue XML-dokumentti koostuu yhdestä (juuri)elementistä, jolla tyyppinimi". Elementit koostuvat hierarkisesti XML-elementeistä ja/tai tekstistä. Samannimisiä elementtejä voi yhden elementin sisällä olla useita. Elementti kenttä (mahdollisesti nimiongelmia). HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.37/66
XML-dokumentin luonnehdintaa 2/3 Elementeillä voi olla tekstiarvoisia nimettyjä attribuutteja. <kappale tasaus="both"> Tämä tasataan molempiin reunoihin... </kappale> Elementillä ei ole pakko olla sisältöä. <graphic source="kissa.gif"/> Jos tagit noudattavat hierarkista rakennetta ja vain yksi juurielementti, on dokumentti oikeanmuotoinen (well-formed) XML-dokumentti. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.38/66
XML-dokumentin luonnehdintaa 3/3 Määrittävätkö elementit sisällölle merkityksen? Elementtien nimet voi valita vapaasti joten mistä yhteys sisällön merkitykseen? DTD. XML:ssä voitaisiin tulla toimeen ilman attribuutteja niiden tieto voitaisiin esittää sisältyvillä elementeillä. XML suunniteltu hyvin? HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.39/66
DTD, yleistä 1/2 XML-dokumentin ei tarvitse olla minkään DTD:n mukainen! (Document Type Definition) Jos dokumentin rakenne vastaa DTD:tä, sanotaan dokumenttia validiksi. DTD eli dokumentin rakennemääritys; verrattavissa ohjelmointikielissä tyyppiin. DTD:n tekemiseksi oma kieli (osa XML:ää). Dokumentin alussa voi olla ulkoisen DTD:n määre <?xml version="1.0"> <!DOCTYPE sahkoposti <sahkoposti>... </sahkoposti> SYSTEM "sposti.dtd"> HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.40/66
DTD, yleistä 2/2 tai sisäisen DTD:n määre: <?xml version="1.0"> <!DOCTYPE sahkoposti [ <!ELEMENT sahkoposti (lahettaja, vastaanottajat, otsikko, runko)> <!ELEMENT lahettaja (email, nimi?)>... ]> <sahkoposti>... </sahkoposti> DTD:n ELEMENT-määrittelyiden apuna käytetään ENTITY-määreitä, jotka ovat vakioita / makroja / ulkoisia tiedostoja. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.41/66
DTD-esimerkki: sposti.dtd Esimerkki sposti.dtd: <!ELEMENT sahkoposti (lahettaja, vastaanottajat, otsikko, runko)> <!ELEMENT lahettaja (email, nimi?)> <!ELEMENT email (#PCDATA)> <!ELEMENT nimi (#PCDATA)> <!ELEMENT vastaanottajat (vastaanottja)+> <!ELEMENT vastaanottaja (email nimi)> <!ELEMENT otsikko (#PCDATA)> <!ELEMENT runko (kappale)*> <!ELEMENT kappale (#PCDATA)> HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.42/66
DTD: kuvauksesta tarkemmin Määreet: (tai),? (0/1), + ( 1), * (> 0). Listassa (A, B, C) järjestys on sidottu. Kentän tyyppi: monikko, EMPTY, ANY, #PCDATA. <!ATTLIST...> määrittelee attribuutit. Jäsentämäton entiteetti (ulkoinen): <!ENTITY kustantajanlogo SYSTEM "../pics/logo.gif" NDATA gif> Yleisentiteetti (viite: &XML;): <!ENTITY XML "Extensible Markup Language"> HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.43/66
Attribuuteista Mahdollista laittaa elementtiin identiteetti <!ATTLIST book id ID #REQUIRED> #REQUIRED (vaaditaan), #IMPLIED (sovellus päättää), #FIXED (kiinteä, ilmoitetaan). Muut tyypit ID:n lisäksi: IDREF viittaa ID:hen (täytyy olla olemassa) ENTITY DTD:ssä määrätty entiteetti lisäksi muita HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.44/66
XML:n muita rakenneosia Skeemat (scheme) ovat DTD:n korvaajia, jotka ovat ilmaisuvoimaltaan parempia. Dokumentti olio; skeema luokka. Nimiavaruus (namespace) on tapa yhdistää dokumentissa eri DTD-määrityksistä otettuja elementtejä, vaikka niillä olisi sama nimi. XSL (Extensible Stylesheet Language) mahdollistaa XML-dokumentin kuvaamisen toisenlaiselle merkkauskielelle. Joukko kuvaussääntöjä; kohteena esim. HTML tai WML. XLink, XForms, XPointer, XHTML, XPath, XSLT, XInclude, XQuery, XML Signatures, HOJ, jnec Ville Leppänen, IT, Turun yliopisto, 2012 p.45/66
XML ja Java DOM = Document Object Model Luokista, erityisesti Node Jäsentäminen: Xerces Xerces-esimerkki HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.46/66
DOM = Document Object Model API: XML-dokumentti (Java-)olioina. JDK1.4: org.w3c.dom paketti. Ei ole jäsennin, vaan jäsennyksen tulos. Voidaan käyttää ohjelmalliseen XML-dokumenttien muodostamiseen & muokkaamiseen. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.47/66
DOM-rajapinnan luokkia Element XML-dokumentin elementti. Attr attribuutti. Comment <!-- Kommentti... --> Entity entiteetti (ei määr). Document koko XML-dokumentti. DocumentType DTD-määrittely. Text tekstitietoa. CDATASection tekstiä (CDATA). Node puurakenne edellisille (yliluokka). HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.48/66
Luokka Node Node getfirstchild() Node getnextsibling() Node getprevioussibling() Node getlastchild() Node getparentnode() NodeList getchildnodes() String getnodename() String getnodevalue() Document getownerdocument() NamedNodeMap getattributes() vain elementeille. boolean hasattributes() boolean haschildnodes() Muuttaminen: appendchild, removechild, replacechild, setnodevalue,... HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.49/66
Jäsentäminen: Xerces XML Apache-projektin tulos; 1.0:n mukainen jäsentäjä. Eräs jäsentäjä; xml.apache.org Idea: tekstitiedosto ajonaikaisia Java-olioita. Tuloksena org.w3c.dom.document. Tukee validointia. Antaa toteutuksen JDK1.4:n paketille org.w3c.dom (ja javax.xml.parsers). XML Apache:een liittyy myös Xalan, jolla voidaan käsitellä XSL-määrityksiä. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.50/66
Xerces esimerkki import org.apache.xerces.parsers.domparser; import org.w3c.dom.document; import org.xml.sax.saxexception; import java.io.ioexception;... String xmlfile = "file:///xerces-1_4_4/data/personal.xml"; DOMParser parser = new DOMParser(); try { parser.parse(xmlfile); } catch (SAXException se) { se.printstacktrace(); } catch (IOException ioe) { ioe.printstacktrace(); } Document document = parser.getdocument(); HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.51/66
ViestiPalvelin.java import java.io. ; import java.net. ; import java.util. ; public class ViestiPalvelin { public static final int VIESTIPORTTI = 8203; public static void main(string[] args) throws Exception { ServerSocket ss = new ServerSocket(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); is.close(); cs.close(); System.out.println("Message from " + sp.lähettäjä.email); } // while } // main } // class ViestiPalvelin HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.52/66
Viestittaja.java import java.net. ; import java.io. ; public class Viestittaja { public static void main(string[] args) throws Exception { if (args.length 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 HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.53/66
XMLsposti.java 1/12 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 class XMLsposti { 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"; HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.54/66
XMLsposti.java 2/12... public static Sposti parse(inputstream xmlin) throws Exception { DOMParser parser = new DOMParser(); 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; String aihe = null; Vector vastaanottajat= new Vector(); Vector kappaleet = new Vector(); ch = seekfor(ch, Node.ELEMENT_NODE); while (ch 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); HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.55/66
XMLsposti.java 3/12 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 muodostus int 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 HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.56/66
XMLsposti.java 4/12 private static Node seekfor(node n, short t) { while ((n null) && (n.getnodetype() t)) n = n.getnextsibling(); return n; } // seekfor private static String parseotsikko(node n) { return n.getfirstchild().getnodevalue(); } // parseosoite 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()); HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.57/66
XMLsposti.java 5/12 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 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ä HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.58/66
XMLsposti.java 6/12 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 null) { if (!child.getnodename().equals(vastaanottaja)) throw new Exception("Outo elem: " + child.getnodename()); vec.add(parsevastaanottaja(child)); child = seekfor(child.getnextsibling(), Node.ELEMENT_NODE); } // while return vec; } // parsevastaanottajat HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.59/66
XMLsposti.java 7/12 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 new Exception("Vieras elementti: " + nn); Vastaanottaja v = new Vastaanottaja(); v.email = email; v.nimi = nimi; return v; } // parsevastaanottaja HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.60/66
XMLsposti.java 8/12 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 null) { if(!child.getnodename().equals(kappale)) throw new Exception("Odotettiin elementtiä: "+ KAPPALE); vec.add(child.getfirstchild().getnodevalue()); child = seekfor(child.getnextsibling(), Node.ELEMENT_NODE); } // while return vec; } // parserunko HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.61/66
XMLsposti.java 9/12 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)); HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.62/66
XMLsposti.java 10/12 Element nimi = doc.createelement(nimi); lähettäjä.appendchild(nimi); nimi.appendchild(doc.createtextnode(sp.lähettäjä.nimi)); // Vastaanottajat for (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 HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.63/66
XMLsposti.java 11/12 // Otsikko otsikko.appendchild(doc.createtextnode(sp.otsikko)); // Runko for (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 HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.64/66
XMLsposti.java 12/12 class Sposti { public Lahettaja lähettäjä; public Vastaanottaja[] vastaanottajat; public String otsikko; public String[] kappaleet; } // Sposti class Lahettaja { public String email; public String nimi; } // Lahettaja class Vastaanottaja { // Toinen aina null. public String email; public String nimi; } // Vastaanottaja HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.65/66
Lopuksi XML on nykyään hyvin keskeinen osa tietotekniikkaa. Kehittyy tulevaisuudessa, mutta tuskin kuolee pois. Kannattaa opetella XML:n käyttö Javan kannalta. Protokollan suunnittelu ja dokumentointi tärkeää. Viestit kannattanee esittää Java-ohjelmissa luokkina. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.66/66