Tekijä: Marko Seppänen
Teostyyppi: harjoitustyö
Oppilaitos: Saimaan ammattikorkeakoulu
Julkaisuajankohta: Joulukuu 2009
Kurssi: Hajautetut sovellukset
1 Johdanto
2 Service-Oriented Architecture (SOA)
3 Web Services
3.1 Taustaa
3.2 WSDL JA SOAP
3.3 Mallidokumentteja ja käsittely Javalla
3.3.1 WSDL-dokumentti
3.3.2 WDSL-lukija
3.3.3 OXYGEN XML:n WDSL/SOAP -analysaattori
3.3.4 SOAP-viesti
3.3.5 SOAP-lukija
3.4 UDDI
3.4.1 Global Biodiversity Information Facility (GBIF)
3.5 WS-standardit
3.5.1 Taustaa
3.5.2 Esimerkkejä WS-standardeista
4 Ohjelmointikielisidonnaiset
4.1 RMI
4.1.1 Etämetodin kutsu RMI:n kautta
4.2 Google Web Toolkit -RPC
4.2.1 Etämetodin kutsu GWT-sovelluksessa
5 Sisällön ammennus
5.1 Ohjelmistorajapintoja (API)
5.1.1 REST
5.2 Mashupeja
5.2.1 AJAX
5.3 EMML
5.3.1 Koodipoimintoja
6 XML, XSL ja XPath
6.1 XML on laajennettavissa oleva merkkauskieli
6.1.1 XML
6.1.2 DTD
6.1.3 XML Schema
6.1.4 XSLT
6.1.5 XPath
6.2 XML-tiedostomuotoja
6.2.1 IDML (InDesign Markup Language)
6.2.2 HL7 (Health Level Seven)
6.3 XML-dokumentin käsittely Javalla
6.4 Relaatiotietokannasta XML-dokumentiksi
7 Järeämmät
7.1 CORBA
7.2 ebXML
7.3 RosettaNet
8 Lähteet
Hajautettuihin sovelluksiin tutustumiseen ja syventymiseen voisi käyttää loputtomasti aikaa. Tämän dokumentin luomisprosessin tarkoituksena on ollut saada tuntumaa sekä hajautettujen sovellusten eri muodoista, että asiakas–palvelin -kutsuista. Pienimuotoisimmillaan hajautettu järjestelmä voi koostua pienestä joukosta etäkutsuja, joihin vastaajan sijainnista ei ole tietoa, eikä sitä tarvitsekaan tietää, koska riittää, että välittäjänä toimiva rekisteri tietää sen. Tälläinen olisi esim. ohjelmointikieli Javaan sidottu RMI-kutsu. Järeämmissä järjestelmissä asiakaspuolen ja palvelua tarjoavien puolien käyttämillä eri ohjelmointikielillä ei ole mitään merkitystä (CORBA) tai sitten käytössä on niin jykevä standardi, että se satojen eri instanssien käyttämien sovellusten yhteentoimivuuden jotain huolella määriteltyä standardia noudattaen (HL7). Lukujen yhteisenä sidosteena toimivat suuressa määrin ohjelmointikieli Java, sekä merkkauskieli XML.
Ihmiset ja organisaatiot luovat valmiuksia ratkaisemaan tai tukemaan ratkaisua ongelmiin, joita he kohtaavat toiminnassaan. On luonnollista ajatella yhden ihmisen tarpeet voitavan täyttää valmiuksilla, joita joku toinen tarjoaa; tai, hajautetun laskennan maailmassa, yhden tietojärjestelmän tarpeet voitavan täyttää tietojärjestelmällä, joka kuuluu jollekin toiselle. (Nickull ym. 2007, vapaa suomennos)
Toiminnassa olevan julkisen verkkopalvelun tai yrityksen privaatissa lähiverkossa (intranetissä) käytössä olevan keskitetyn palvelun arkkitehtuurin muuntaminen hajautetuksi eli liiketoimintalogiikan ja yksittäisten metodien modularisoiminen ja esittäminen palveluina asiakasohjelmistoille (Raghu 2005), voi olla perusteltua silloin, jos esimerkiksi jokin arkkitehtuurin komponentti halutaan kustannus- tai tehokkuussyistä ulkoistaa jonkin toisen palveluntarjoajan toteuttamaksi. Komponentti voi olla esim. yksittäinen tietokanta, tekstin kieliopin tarkistaja, kartta-arkiston hallintaohjelma tai fraktaalilaskin. Luonnollisesti hajauttaminen voi rajautua myös konsernin/organisaation sisällä tarjottaviksi ja käytettäviksi palveluiksi.

Kuva 1. Sunin havainnollistava esitys SOA-ohjelmistosuunnitteluperiaatteen vaikutuksesta
Syynä hajautukseen voi olla sekin, että komponenttien välinen viestiliikenne käyttää useaa eri tiedonvälitystapaa ja koetaan, että yhtenäistäminen on toiminnan hahmottamisen kannalta hyödyllistä. Ulkoisen palvelun käyttötapauksena voi olla jotain niinkin pientä kuin yksittäisen etämetodin kutsuminen esim. sen tautta, että joku on kehittänyt ja tarjoaa ilmaiseksi tai maksua vastaan käytettäväksi jonkin tietyn rakenteisen datan käsittelemiseen paremman algoritmin.
Verkkopalveluita käytettäessä ei ole niin välillä sillä, ovatko esim. laitealustat ja palveluntarjoajan oman arkkitehtuurin komponenttien välinen viestintä mihin teknologioihin nojautuvaa (esim. toisessa voi olla Linux-palvelin ja toisessa Windows-palvelin). Riittää, että molemmat osapuolet noudattavat samoja standardeja ja niiden versioita.
Tietyt teknologiat eivät ota tiedon salaukseen kantaa lainkaan toisin kuin eräät toiset hajautettujen sovellusten teknologiat, mm. CORBA. XML:n käyttö välitetyn tiedon rakenteelliseen esittämiseen tekee kommunikoinnista helpompaa, mutta aivan kaikissa tapauksissa se ei välttämättä ole paras ratkaisu. Näin esimerkiksi silloin, jos tarpeen on siirtää paljon tietoa (esim. videodata). Verkkopalvelut, joilla tavanomaisesti viitataan teknologioihin SOAP, WSDL ja UDDI, eivät tarjoa esimerkiksi sisäänrakennettua käyttäjäntunnistusta, tietoturvaa, kuormantasausta tai automaattista virheistä toipumista. Verkkopalveluilla tiedon salaus hoidetaan yleensä HTTPS-protokollan avulla, mutta myös muitakin ratkaisuja on ehdotettu. Yksi tällainen ehdotus on Microsoftin WS-Security (Järvinen 2002).

Verkkopalveluilla (englanniksi web services) tarkoitetaan sovelluksia, jotka voivat keskustella toisten verkkopalveluiden kanssa käyttäen standardeja protokollia ja tiedonvälityskanavanaan Internetiä (Järvinen 2002). Keskustelu tarkoittaa tässä sitä, että yksi verkon palvelu pyytää toista verkkopalvelua toteuttamaan jonkin asian ja mahdollisesti, mutta ei välttämättä, lähettämään vastausviestinä joko pelkän kuittauksen tai varsinaisen vastauksen (esim. pyydetyn raportin).
Käytännössä kutsutaan toisen verkkopalvelun tarjoamia palveluita, jotka voivat olla pyyntöjä (”käytä algoritmia x seuraavaan merkkijonoon ja palauta algoritmin tuottama uusi merkkijono”), kyselyjä (”hae kaikki henkilön x aiemmat osoitteet”) tai käskyjä (”sammuta tuuletin”). Käydyn keskustelun viestintäkieleni on yleensä XML-kieli, joka välitetään tiedonvälitysprotokolla HTTP:n avulla. Huomioitavaa on sekin, että sekä etämetodeita käyttöönsä tarjoava, että kutsuja, voivat molemmat toimia kummassa tahansa roolissa eli ei välttämättä niin, että toinen on asiakas ja toinen palvelija. Sovelluskehittäjän kannalta olennaista on, että tiedossa on kohdepalvelun osoite sekä metodin nimi.
Jotta käytettävissä olevista metodeista voitaisiin tulla tietoiseksi, on verkkopalveluita tarjoava organisaatio tai muu palvelutarjontaa ylläpitävä taho julkaissut WSDL-dokumentin, joka kertoo sitä ymmärtävälle ohjelmistolle mitä palveluita on tarjolla. WSDL-dokumentti on XML-kielinen rakenteinen dokumentti. Metodeita kutsutaan lähettämällä palvelimella SOAP-viesti, joka on myös XML-dokumentti. SOAP-viestejä kutsutaan myös kirjekuoriksi. Rakenteeltaan ne ovat seuraavanlaisia:

Kuva 2. SOAP-viestin rakenne
SOAP-standardi ei määrittele, mitä otsikon pitäisi sisältää, vaan otsikossa (header) olevat tiedot voidaan määritellä sovelluskohtaisesti. Runko-osa (body) on aina pakollinen osa SOAP-viestiä, mutta standardi (v1.1) ei määrittele sitäkään, mitä tarkalleen sen pitää tai ei pidä sisältää. SOAP-standardi määrittelee kuitenkin perustan, jolla esim. erilaisia tietotyyppejä voidaan esittää SOAP-viesteissä. WDSL-standardi ei ota kantaa siihen mitä viestit sisältävät, eikä myöskään siihen, mitä protokolla tiedonvälitykseen käytetään, mutta yleisimmin käytetään juurikin SOAP:tä ja HTTP:tä (Järvinen 2002).
Alla on esitetty WSDL-dokumenttien selkeisiin lohkoihin jaettu perusrakenne. Usein näiden dokumenttien tuottamiseen käytetään jotain työkaluja.

Kuva 3. WSDL-dokumentin rakenne
WSDL:n termistössä types määrittelee käytetyt tietotyypit, message määrittelee viestit joita voidaan välittää sovellusten välillä, portTypeä käytetään määrittelemään ne operaatiot, joita palvelu tukee, binding määrittelee tekniset yksityiskohdat viestin välitettämiselle käytännössä, service kertoo kutsuvalle sovellukselle, mistä verkko-osoitteesta halutut palvelut löytyvät.
Seuraavassa esimerkissä palveluntarjoaja on tiedossa, kuten myös WSDL-tiedoston url-osoite, sillä riittävä ohjeistus on kerrottuna palvelun tarjoavan organisaation (National Center for Biotechnology Information, NCBI) verkkosivuilla. Esimerkissä käydään läpi wdsl-tiedoston luentaa ja SOAP:ia läpi sen verran, että lukija saa alustavaa tuntumaa siitä kuinka niitä palvelun käyttäminen tapahtuisi Javalla.
WSDL-tiedosto löytyy osoitteesta: http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/efetch_pubmed.wsdl
<?xml version="1.0"?>
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s0="http://www.ncbi.nlm.nih.gov/soap/eutils/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://www.ncbi.nlm.nih.gov/soap/eutils/" xmlns:nsef="http://www.ncbi.nlm.nih.gov/soap/eutils/efetch_pubmed">
Tiedosto sisältää aluksikin nimiavaruusmääritelmät, joiden jälkeen tulevat datan kuvaus ja käytettävissä olevat metodit. Tämä rajapinta ei tarjoa kuin yhden toiminnon eli abstraktien metatiedon haun.
<types>
<xs:schema>
<xs:import namespace="http://www.ncbi.nlm.nih.gov/soap/eutils/efetch_pubmed"
schemaLocation="efetch_db_pubmed.xsd" />
</xs:schema>
</types>
<message name="eFetchRequest_m">
<part name="inpp" element="nsef:eFetchRequest" />
</message>
<message name="eFetchResponse_m">
<part name="outp" element="nsef:eFetchResult" />
</message>
<portType name="eUtilsServiceSoap">
<operation name="run_eFetch">
<input message="s0:eFetchRequest_m" />
<output message="s0:eFetchResponse_m" />
</operation>
Tiedosto sisältää standardin mukaisesti liittymän tyypin ja datan siirtotavan, sekä mihin operaatioon nämä kytketään.
<binding name="eUtilsServiceSoap" type="s0:eUtilsServiceSoap"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="run_eFetch"> <soap:operation soapAction="efetch" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding>
<service name="eFetchPubmedService"> <port name="eUtilsServiceSoap" binding="s0:eUtilsServiceSoap"> <soap:address location="http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/soap_adapter_2_0.cgi?db=pubmed" /> </port> </service> </wsdl:definitions> |
Toisessa saman palveluntarjoajan WSDL-tiedostossa, jolla käsitellään samoja etätietokantoja, olisi lukuisampi määrä eri toimintoja. Sitä voi tarkastella osoitteesta:
http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/eutils.wsdl
Seuraava koodi hyödyntää JDK:n (Java Development Kit) mukana tulevia Java-luokkia WSDL-lukijan luomiseen ja käytettävissä olevien palveluiden keräämiseen Map-tietorakenteeseen.
import java.util.Map; import java.util… import javax.wsdl…
class WSDLTest {
public String testMethod() {
String endpoint = "http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/efetch_pubmed.wsdl"; Definition definition = null;
try { WSDLFactory wsdlFactory = WSDLFactory.newInstance(); WSDLReader wsdlReader = wsdlFactory.newWSDLReader();
wsdlReader.setFeature("javax.wsdl.verbose", false); wsdlReader.setFeature("javax.wsdl.importDocuments", true);
definition = wsdlReader.readWSDL(endpoint); if (definition == null) { System.err.println("definition element is null"); System.exit(1); } else { System.err.println("hyivn menio"); }
} catch (WSDLException ex) { Logger.getLogger(WSDLTest.class.getName()).log(Level.SEVERE, null, ex); }
Map map = definition.getServices(); String output = map.toString(); return output; } } |
Operaatio eFetchin käyttämiseksi on palveluntarjoajalle lähetettävä SOAP-protokollaa käyttäen viesti, jota kuvaavana on alla Oxygen XML -ohjelman avulla haettu mallitemplaatti lähetettävälle viestille.

Kuva 4. Malli lähtevästä SOAP-viestistä.
Sitä, mitä SOAP-viestin Body-kentässä lähetetään, ei ole sidottu mihinkään muihin vaatimukseen kuin niihin, että viestin täytyy olla XML-merkintäkielen mukainen ja se ei voi olla tyhjä.
Oletettakoon, että aikomuksena on noutaa abstraktin nro 19852072 tiedot. Tätä tarkoitusta varten ei ole tarpeellista täyttää kaikkia parametrejä, vaan riittää kun kertoo id-numeron. Palveluntarjoaja on mahdolistanut saman tiedon kutsumisen eri tavoin, joten seuraavan SOAP-kyselyn vastausviesti olisi PubmedArticleSet-tagista alkaen identtinen sille, jos käyttäisi REST-tyyppistä GET-metodillista kyselyä eli käytännössä kirjoittaisi selainriville:
http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=19852072&retmode=xml
Tarkoitus on lähettää seuraavanlainen SOAP-viesti:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <eFetchRequest xmlns="http://www.ncbi.nlm.nih.gov/soap/eutils/efetch_pubmed"> <id>19852072</id> </eFetchRequest> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
JDK:stä löytyy sopivasti myös tätä tarvetta varten omat pakkauksensa, joten SOAP:n hyödyntäminen helpottuu huomattavasti. Javalla kyselyn pohjustus tehtäisiin seuraavanlaisesti:
import java.io...
import java.util...
import javax.xml.soap...
import javax.xml...
class SOAPTest {
public String testMethod() {
String output = null;
try {
// create the connection
SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnFactory.createConnection();
// create the actual message
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
String SOAPUrl = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/soap_adapter_2_0.cgi";
String SOAPAction = "egquery";
message.getMimeHeaders().setHeader("SOAPAction", SOAPAction);
// create objects for the message parts
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader soapHeader = envelope.getHeader();
SOAPBody body = envelope.getBody();
SOAP-kirjeeseen liitettävän viestin sisältä luetaan XML-tiedostosta:
// populate the Message StreamSource preppedMsgSrc = new StreamSource(new FileInputStream("soap-request.xml")); soapPart.setContent(preppedMsgSrc);
// save the message message.saveChanges();
// send the message SOAPMessage reply = connection.call(message, SOAPUrl); |
Seuraavassa olennaista on rivi, jolta löytyy reply.getSOAPPart().getContent(), koska sillä saadaan noukittua vastauksena saadun SOAP-viestin sisältökenttä (Body) käsittelyyn.
// Create the transformer TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer();
// Extract the content of the reply Source sourceContent = reply.getSOAPPart().getContent();
StringWriter sw = new StringWriter(); StreamResult sr = new StreamResult(sw); try { transformer.transform(sourceContent, sr); } catch (TransformerException ex) { Logger.getLogger(DOM4JParser.class.getName()).log(Level.SEVERE, null, ex); } output = sw.toString();
// Close the connection connection.close();
} catch (Exception e) { System.out.println(e.getMessage()); }
return output;
} } |
Alla ote vastauksena saadusta XML-tiedostosta. Sillä voi tehdä haluamansalaista jatkokäsittelyä, kuten esimerkiksi transformoinnin XSL-tyylitiedoston avulla.
<?xml version="1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <eFetchResult xmlns="http://www.ncbi.nlm.nih.gov/soap/eutils/efetch_pubmed"> <PubmedArticleSet> <PubmedArticle> <MedlineCitation Owner="NLM" Status="Publisher"> <PMID>19852072</PMID> <Article PubModel="Print-Electronic"> <Journal> <ISSN IssnType="Electronic">1098-2396</ISSN> <JournalIssue CitedMedium="Internet"> <Volume>64</Volume> <Issue>2</Issue> <PubDate> <Year>2009</Year> <Month>Oct</Month> <Day>22</Day> </PubDate> </JournalIssue> <Title>Synapse (New York, N.Y.)</Title> <ISOAbbreviation>Synapse</ISOAbbreviation> </Journal> <ArticleTitle>Altered response to antidepressant treatment in FoxG1 heterozygous knockout mice.</ArticleTitle> </Article> </MedlineCitation> </PubmedArticle> </PubmedArticleSet> </eFetchResult> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |

UDDIa voi ajatella hajautettuna rekisterinä, josta löytyy tietoja erilaisten yritysten tarjoamista verkkopalveluista ja jossa olevia tietoja voidaan hakea, lisätä ja muokata ohjelmallisesti (Järvinen 2002). Kompaktisti sanottuna UDDI-rekisteri toimii siten, että sille lähetetään SOAP-viesti, saaden vastauksena WSDL-dokumentti, joka kertoo mistä on löydettävissä tiedustellun kaltaisia palveluja ja tarkempaa tietoa kutsuttavissa olevista metodeista. UDDI-rekisterit organisoivat tietoa käyttäen seuraavien tyyppisiä tietomallin osa-alueita: palvelun julkaisijan kuvaus (business entities), palvelun kuvaus (business services), sekä palvelun tekninen kuvaus ja viite ohjelmointirajapintaan (business template).

Kuva 5. UDDI v3.0:n ydinrakenne
Vuonna 2005 Microsoftin, IBM ja SAP ilmoittivat yhteenliittymänsä universaalin UDDI-rekisterin pidossa päättyneeksi, eikä heidän yhteisestä julkisesta rekisteristään voinut enää hakea tietoa vuoden 2006 tammikuun 12. päivä jälkeen. Kuitenkin, tämän vuonna 2000 alkaneen projektin ilmoitettiin (Microsoft 2005) olleen menestyksekäs; UDDI osoitti lausumien mukaan (SAP News Desk 2005) yhteentoimivuutensa ja spesifikaation laadukkuuden. Jokaiselle näistä tahoista on UDDI-palvelu sisällytettynä tiettyihin tarjoamiinsa ohjelmistotuotteisiinsa. Yhteisen rekisterin ylläpidon aikana UDDI ehti saavuttaa versionumeron 3 ja siitä tuli eräs OASIS:än standardeista (OASIS 2004). Syiksi lopettamispäätöksellä luetaan myös se, että yritysten tapa toimia markkinoilla on muuttunut eli kaikki eivät halua olla samassa rekisterissä. Eri tahoilla on edelleen omia UDDI-rekisterereitään.
Yksittäisen yrityksen tarjomien palvelujen sijaintiedosta esimerkkidokumentti ajalta, jolloin Microsoft, muiden muassa, vielä tarjosi universaalia UDDI-rekisteripalvelua.
<?xml version="1.0"?> <businessEntity xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" businessKey="e9355d51-32ca-49cf-8eb4-1ce59afbf4a7" operator="Microsoft Corporation" authorizedName="Thomas Erl" xmlns="urn:uddi-org:api_v2"> <discoveryURLs> <discoveryURL useType="businessEntity">http://test.uddi.microsoft.com/discovery ?businesskey=e9355d51-32ca-49cf-8eb4-1ce59afbf4a7 </discoveryURL> </discoveryURLs> <name xml:lang="en"> XMLTC Consulting Inc </name> <description xml:lang="en"> XMLTC has been building end-to-end enterprise eBusiness solutions for corporations and government agencies since 1996. We offer a wide range of design, development and integration services </description> <businessServices> <businessService serviceKey="1eeecfa1-6f99-460e-a392-8328d38b763a" businessKey="e9355d51-32ca-49cf-8eb4-1ce59afbf4a7"> <name xml:lang="en-us"> Corporate Home Page </name> <bindingTemplates> <bindingTemplate bindingKey="48b02d40-0312-4293-a7f5-4449ca190984" serviceKey="1eeecfa1-6f99-460e-a392-8328d38b763a"> <description xml:lang="en"> Entry point into the XMLTC Web site through which a number of resource sites can be accessed </description> <accessPoint URLType="http"> http://www.xmltc.com/ </accessPoint> <tModelInstanceDetails /> </bindingTemplate> </bindingTemplates> <categoryBag> <keyedReference tModelKey="uuid:c1acf26d-9672-4404-9d70-39b756e62ab4" keyName="Namespace" keyValue="namespace" /> </categoryBag> </businessService> </businessServices> </businessEntity> |
Eräs erinomainen esimerkki UDDI:n hyödyllisyydestä on Global Biodiversity Information Facilityn (GBIF) tarjoama informaatioinfrakstuuri; indeksi internet-pohjaiselle, maailmanlaajuisesti hajautetulla, yhteentoimiville tietokannoille, jotka sisältävät tietoa biodiversiteetistä eli luonnon monimuotoisuudesta. Käytännössä mm. tietoa museoiduista kohteista, eläin- ja kasvihavainnoista, kokeiluista. Palvelu on kaikkien käytettävissä.
GBIF:n UDDI-osoite: http://registry.gbif.net/uddi/inquiry
Edellinen sisältää viitteet seuraaviin WSDL-dokumentteihin, jotka kertovat tarkemmin palvelutarjonnasta:
WSDL 1.0: http://registry.gbif.net/uddi/inquiry/uddi_inquiry_v1.wsdl
WSDL 2.0: http://registry.gbif.net/uddi/inquiry/uddi_inquiry_v2.wsdl
Palvelu on myös hyvä esimerkki siitä, sitten kuitenkin, kuinka vaikea on kehittää sellaista kuvausstandardia, joka sopisi kaikkiin käyttökohteisiin. Tässä tapauksessa ongelma ilmenee esim. eri instanssien, kokoelmien ja varantojen välisten suhteiden määrittelemisessä:
However a UDDI alone falls short of mapping the full complexity of the networked GBIF community and does not address more complex issues such as understanding of roles and relationships between institutions, collections and resources. For example, within the DarwinCore schema, the two fundamental concepts (InstitutionCode and CollectionCode), are intended to refer to a “standard” code identifier that uniquely identifies the institution and collection. However, no global registry exists for assigning unique, standardised institutional (and collection) codes that publishers should use across the various disciplines. (GBIF 2009)
Verkkopalvelujen yhteentoimivuuden kehittämiseksi WS-I julkaisee profiileja, jotka määrittävät spesifikaatiot sille, kuinka SOAP-viestejä ja WSDL:lää käytetään siten, että tietyt esim. tietoturvallisuuteen viestien kulkeutumiseen, transaktioihin, metadataan tai liiketoimintaprosesseihin liittyvät vaatimukset tulisivat täytetyksi.
Kuriositeettina mainittakoon, että WS-I on organisaatio, jonka alun perin perustivat mm. IBM ja Microsoft, ilmeisesti erityisesti jälkimmäisen haluna ollen se, että perustajajäseneksi ei hyväksyttäisi Sunia:
E-mail messages from Microsoft Chairman Bill Gates and other executives, introduced during testimony last week, offer rare insight into the political maneuverings of the company. In an e-mail to top executives, Gates indicated that he approved of Microsoft's involvement with the Web Services Interoperability Organization (WS-I) as long as Sun's role was minimized. (Wong 2002)
Informaatioteknologia-alan yrityksille tutkimus- ja neuvonantopalveluita tarjoava Gartner esitti tuolloin sekin oman arvionsa siitä miten kiistassa käynee eli että pääseekö Sun perustajajäseneksi vai eikö:
Gartner believes that, despite their continuing differences, Sun will join WS-I and that IBM and Microsoft will join Liberty by 2004 (0.6 probability). Gartner further believes that Web services will eventually succeed because of their value in integration and usefulness in simple projects. (Hicks 2002)
Microsoftin lehdistötiedotteessa helmikuulta 6. päivä 2002 kerrotaan (Microsoft 2002) perustajajäseninä olleen ainakin Accenture, BEA Systems Inc., Fujitsu Ltd., Hewlett-Packard Co., IBM Corp., Intel Corp., Microsoft Corp., Oracle Corp. and SAP AG.
Sun oli aiemmin asettanut ehdoksi, että se ei liity organisaatioon kuin sillä ehdolla, että se hyväksytään perustajajäsenä, mutta kertomansa mukaan se oli saanut monelta eri alalla toimijalta pyyntöjä liittyä WS-I:hin, joten se liittyi organisaatioon vielä samaisen vuoden lokakuussa osallistuvana (en. contributing) jäsenenä (Cover Pages 2002). Tuolloinen hallintoneuvosto oli päättänyt lisätä paikkoja neuvostossa kahdella, Sunin vuoksi. Sittemmin WS-I:hin on liittynyt henkilöjäseniä lukuisilta eri tahoilta, erilaisista hallinnollisista, operatiivisista ja teknisistä rooleista.
Konsultointiyritys InnoQ on julkaissut kartan (2007) Web Services -stardardeista. Niitä on lukuisia.

Kuva 6. Kartta Web Services –stardardeista
Kartta PDF-muodossa osoitteessa:
http://www.innoq.com/soa/ws-standards/poster/innoQ
WS-Standards Poster 2007-02.pdf
WS-I Basic Profile 1.0 tarjoaa yhteentoimivuusohjeistuksen sellaisille verkkopalveluiden
ydinspesifikaatioille kuten SOAP, WSDL ja UDDI. WS-I -organisaation sisällä muodostettu
Basic Profile Working Group –ryhmä työstää tällä hetkellä Basic Profile 1.2:ta
ja 2.0:aa. (WS-I 2009)
WS-Security kuvaa SOAP-viesteihin tehtävät muunnokset, joiden tarkoituksena on taata suojauksen laatu viestien eheyden, luotettavuuden ja yksittäisten viestien autentikoinnin kautta. (CDBI 2005)
WS-Policy tarjoaa yleiskäyttöisen mallin ja syntaksin verkkopalveluiden käytäntöjen (en. policies) kuvaamiseen ja kommunikoimiseen. (IBM 2003)
WS-Manageability on määritelty joukkona kykevyyksiä verkkopalvelun olemassaolon, saavutettavuuden, terveyden, tehokkuuden ja käytön selville saamiseksi, sekä verkkopalvelun kontrolloinnimiseksi ja konfiguroimiseksi verkkopalvelun arkkitehtuurin rajoissa (CDBI 2005). Viimeisin implementoitu WS-Management protokolla pohjautuu seuraaviin standardeihin: HTTPS, SOAP over HTTP (WS-I profile), SOAP 1.2, WS-Addressing, WS-Transfer, WS-Enumeration, and WS-Eventing (MSDN 2009).

Java Remote Method Invocation (Java RMI) mahdollistaa sellaisten Java-teknologiaan pohjautuvien hajautettujen ohjelmistojen kehittämisen, joissa etäoliot, joiden metodeita kutsutaan, voivat sijaita tyystin toisella palvelimella kuin missä asiakasohjelmistoa ajetaan. Ennen kuin asiakas pystyy etäoliota kutsumaan, sen täytyy saada viite siihen. Viitteet kutsuttaviin etäolioiden metodeihin sijaitsevat rekisterissä, jonne palvelimena toimiva olio on niitä sijoittanut. Asiakkaan ei ole tarpeen tietää, missä palvelin varsinaisesti sijaitsee, sillä viitteen saatuaan se voi käyttä etäolioita kuin paikallisia vastaavia. Rekisteri voi olla ulkopuolinen ohjelma, esim. JDK:n mukana tuleva rmiregistry tai sovelluksen oma rekisteri.
Rekisterin itsensä käynnistäminen tapahtuu yksinkertaisesti ajamalla shellissä (Windows) seuraava komento:
start rmiregistry
Javan turvallisuusalueet ja säännöt (en. policies) ovat tämän dokumentin käsittelemien aiheiden ulkopuolella, joten yksinkertaisuuden vuoksi palvelin- ja asiakasohjelman käynnistämisen osalta seuraavissa esimerkeissä mennään matalimman aidan yli. Seuraava komento käynnistää palvelinohjelman, Java VM:n parametrinä viittaus policy-tiedostoon, joka antaa käytännössä rajattomat oikeudet palvelinohjelman kutsujalle.
start java -Djava.security.policy=server.policy hello.Server
Tiedoston ’server.policy’ sisältö on seuraavanlainen:
grant { permission java.security.AllPermission; }; |
Tiedosto ‘client.policy’ olisi samanlainen, jotta asiakasohjelman(-olion) olisi mahdollista kutsua etämetodeita. Tarvittavia tiedostoja on vähimmillään kolme, joista kolmas määrittelee etärajapinnan, listaamalla kutsuttavissa olevat metodit. Palvelin toteuttaa tämän rajapinnan ja vie sen käynnistymisensä yhteydessä registeriin, jotta asiakasohjelmakin voi rajapinnan nähdä ja jotta se itse voisi ottaa etäkutsuja vastaan.
Palvelin, sisältäen yhden kutsuttavan metodin ’sum’, näyttää seuraavanlaiselta:
import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; import java.rmi.server.UnicastRemoteObject; import hello.Hello;
public class Server implements Hello {
public Server() { }
public int sum(int a, int b) { return a + b; }
public static void main(String args[]) {
if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
try { Server obj = new Server(); Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0); Registry registry = LocateRegistry.getRegistry(); registry.bind("Hello", stub); System.err.println("Server ready"); } catch (Exception e) { System.err.println("Server exception: " + e.toString()); e.printStackTrace(); } } } |
Rajapintaluokka on kaikessa lyhykäisyydessään seuraavanlainen:
import java.rmi.Remote; import java.rmi.RemoteException;
public interface Hello extends Remote { int sum(int a, int b) throws RemoteException; } |
Asiakas, sisältäen yhden kutsuttavan metodin ’sum’, näyttää seuraavanlaiselta:
import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry;
public class Client {
private Client() { }
public static void main(String[] args) {
if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
try { Registry registry = LocateRegistry.getRegistry(); Hello stub = (Hello) registry.lookup("Hello"); String response = String.valueOf(stub.sum(3, 4)); System.out.println("response: " + response); } catch (Exception e) { System.err.println("Client exception: " + e.toString()); e.printStackTrace(); } } } |
Jos SecurityManageria ei ladattaisi, kutsuja (asiakas tai palvelin) ei voisi ladata muita luokkia kuin niitä, jotka ovat paikallisia eli ei voisi hyödyntää etämetodeita ollenkaan. Etämetodi voi palauttaa primitiivisten tietotyyppien lisäksi myös olioita, ehtona ollen, että ne implementoivat Java-luokan ’java.io.Serializable’.

Googlen Web Toolkit mahdollistaa AJAX:illisten websovellusten kirjoittamisen Java-kielellä, ilman että sovelluskehittäjän tarvitsee tietää Javascriptistä yhtään mitään. GWT kääntää asiakaspuolen koodin sellaiseksi optimoiduksi Javascript-koodiksi, että sovellus toimii kaikissa merkittävimmissä selaimissa yhtäläisesti. Henkilölle, jonka ohjelmointikielien oppiminen on mennyt järjestyksessä ”ensin Javascript, HTML, PHP ja sitten vasta Java”, tässä on jotain fantastista. Tämä muunnos Javasta Javascriptiksi yksinkertaisesti vain toimii, sitä ei missään joudu erityisesti ajatelleeksikaan, että se koodi mitä selainpuolella ajetaan, on Javascriptiä.
Myös olioiden, primitiivityyppien, sekä erilaisten tietorakenteiden ja mallien siirto palvelimelta selaimelle, ja toisinpäin, sujuu näppärästi serialisointia hyödyntäen; oliot ja muut muuntuvat lennossa Java-olioista Javascriptin vastaaviksi.
Javascript asettaa kuitenkin tietyt rajoitukset sille mitä
kaikkea voidaan tai on haluttu Javasta emuloida. Lista emuloiduista
Java-kirjastoista löytyy osoitteesta:
http://code.google.com/webtoolkit/doc/1.6/RefJreEmulation.html
Seuraavassa käydään läpi sellaisen yksinkertaisen GWT-sovelluksen vaatima koodi, missä palvelin vastaa metodikutsuun palauttamalla List-tietorakenteessa nipun itse luodun Message-luokan instansseja. Oman luokan instassin palauttamiseksi verkon yli on luokan implementoitava Serializable-rajapinta. Javan omien luokkien ja primitiivityyppien palauttamiseksi pätevät samat säännöt kuin tietotyyppien määrityksessä yleensäkin eli niiden geneerisyys on määriteltävä.

Kuva 7. Esimerkkiohjelmaan liittyvät muutama tiedostoa.
Kaikki esimerkkiohjelmaan liittyvät tiedostot, joita ohjelmoija itse on joutunut käsittelemään, näkyvät ylhäällä. Hakemistoon war/hello GWT:n kääntäjä vie mm. optimisoidun Javascript-koodin ja muita tarpeellisiksi katsomiaan tiedostoja. Konfiguraatiotiedostossa hello/hello.gwt.xml on olennaista määritys entry-point. Se kertoo mistä luokasta ohjelman käynnistys alkaa. Luokka myös implementoi EntryPoint-rajapinnan.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <module rename-to="hello"> <!-- Inherit the core Web Toolkit stuff. --> <inherits name="com.google.gwt.user.User" />
<!-- Inherit the default GWT style sheet. You can change --> <!-- the theme of your GWT application by uncommenting --> <!-- any one of the following lines. --> <inherits name="com.google.gwt.user.theme.standard.Standard" /> <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> --> <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<!-- Specify the app entry point class. --> <entry-point class="hello.client.Hello" /> </module> |
Sovelluksen käynnistävä luokka ei tee sen kummempaa kuin sen, että se heti alkuunsa lähettää asynkronisen kyselyn palvelimelle ja jää odottamaan vastausta. Vastauksen tullessa ajetaan methodi onSuccess, joka käsittelee onnistuneen kyselyn palauttaman vastauksen.
package hello.client;
import java.util.Iterator; import java.util.List;
import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel;
public class Hello implements EntryPoint {
private final MessageFillerAsync messagefiller = GWT.create(MessageFiller.class);
public void onModuleLoad() {
AsyncCallback<List<Message>> callback = new AsyncCallback<List<Message>>() {
@Override public void onFailure(Throwable caught) {}
@Override public void onSuccess(List<Message> messages) { for (Iterator iterator = messages.iterator(); iterator.hasNext();) { Message message = (Message) iterator.next(); Label label = new Label(message.getTitle()); RootPanel.get().add(label); } } }; messagefiller.getMessages("hello", callback); } } |
MessageFiller-rajapinta implementoi RemoteService-rajapinnan, joka on marker interface ja listaa käytettävissä olevat metodit. Käynnistävässä luokassa luodaan (GWT.create) luokkailmentymä MessageFilleristä, josta tehdään tyyppimuunnos asynkroniseen versioon MessageFillerAsync. Tämän on tarkoitus määrittää takaisinkutsu-metodi, jota kutsutaan kun kysely on käsitelty palvelimella.
package hello.client;
import java.util.List; import hello.client.Message; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; import com.google.gwt.user.client.rpc.RemoteService;
/** * The client side stub for the RPC service. */ @RemoteServiceRelativePath("messagefiller") public interface MessageFiller extends RemoteService {
public List<Message> getMessages(String keyword);
} |
package hello.client;
import java.util.List; import com.google.gwt.user.client.rpc.AsyncCallback;
/** * The async counterpart of <code>MessageFiller</code>. */ public interface MessageFillerAsync {
public void getMessages(String keyword, AsyncCallback<List<Message>> callback);
} |
Eclipseen asennettu GWT-plugini avustaa kehitystyön yhteydessä huomioimaan validin RPC-kutsun mallin luomisessa ja huomauttaa kyllä, jos geneerisyydet, tietotyypit tai parametrit ovat väärin.
Jäljellä olevan palvelinpuolen koodin lisäksi on vielä tiedoston war/WEB-INF/web.xml tiedoston muokkaaminen siltä osin, että sinne lisätään kutsuttavan servletin tiedot. Kun näitä tarvittavia toimenpiteitä tekee ensimmäisiä kertoja, niiden muistaminen voi tuntua hankalalta, mutta jo piankin ne muodostuvat triviaaliksi toimenpiteeksi. Sovelluksen koon kasvaessa voi olla hyödyllistä niputtaa ja lajitella metodikutsuja sopivasti nimettyihin ryhmiin (luokkiin ja paketteihin), jotta sovelluksen rakenteen hahmottaminen omassa mielessään olisi helpompaa.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets --> <servlet> <servlet-name>MessageFillerServlet</servlet-name> <servlet-class>hello.server.MessageFillerServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>MessageFillerServlet</servlet-name> <url-pattern>/hello/messagefiller</url-pattern> </servlet-mapping>
<!-- Default page to serve --> <welcome-file-list> <welcome-file>hello.html</welcome-file> </welcome-file-list>
</web-app> |
MessageFillerServlet-luokka sisältää MessageFiller-rajapinnassa määritellyn getMessages-metodin. Tässä tapauksessa se kääräisee List-tietorakenteeseen 3 kpl Message-luokan ilmentymiä, joihin on kirjattu mukaan lyhyt viesti.
package hello.server;
import java.util.ArrayList; import java.util.List;
import com.google.gwt.user.server.rpc.RemoteServiceServlet; import hello.client.MessageFiller; import hello.client.Message;
/** * The server side implementation of the RPC service. */ @SuppressWarnings("serial") public class MessageFillerServlet extends RemoteServiceServlet implements MessageFiller {
public List<Message> getMessages(String keyword) {
List<Message> messages = new ArrayList<Message>();
if (keyword.equals("hello")) {
for (int i = 0; i < 3; i++) { Message message = new Message(); message.setTitle("Hello message nro " + i); messages.add(message); }
} return messages; } } |
Message-luokka näyttää seuraavanlaiselta:
package hello.client; import java.io.Serializable;
public class Message implements Serializable {
private String title; private String content;
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; } } |
On tiettyjä rajoitteita ja ehtoja sille, mitä voidaan välittää serialisoituna. Tietotyyppi on serialisoitavissa, jos jokin seuraavista ehdoista pätee:
- Tietotyyppi on primitiivityyppi, kuten char, byte, short,
int, long, boolean, float tai double.
- On Stringin tai Daten instanssi, tai primitiivityypin kääreluokka kuten Character,
Byte, Short, Integer, Long, Boolean, Float tai Double.
- On serialisoitu itse luotu luokka.
Muista ehdoista lisää tietoa osoitteesta:
http://code.google.com/webtoolkit/doc/1.6/DevGuideServerCommunication.html#DevGuideSerializableTypes

Puheena ollessa websovelluksien kehittäminen, tarkoitetaan mashupilla jotain sellaista, joka yhdistelee dataa tai funktionaalisuutta kahdesta tai useammasta ulkoisesta lähteestä luodakseen uuden palvelun. Termi mashup viittaa helppouteen, nopeaan integrointiin, sekä avointen API:den (ohjelmistorajapinnat) ja ja datalähteiden hyödyntämiseen tavalla, joka ei ehkei ollut datan tarjoavan itsensä alkuperäinen näkemys datan käytöstä.
![]()
EBI API
http://www.ebi.ac.uk/Tools/webservices/
Rajapinnan englanninkielinen kuvaus: The EBI Web services let you access nucleic acid, protein sequence, and macromolecular structure data. Choose from about 35 EBI Web Services. The European Bioinformatics Institute (EBI) is part of the European Molecular Biology Laboratory (EMBL). The Web services offer DNA and protein sequences, text mining, structure comparisons, various BLASTs, transmembrane topology predictions, microarray searching, and more. (WSDL, SOAP, REST)

KEGG API
http://www.genome.jp/kegg/soap/
Rajapinnan englanninkielinen kuvaus: The increasing amount of genome sequence data is the basis for understanding life as a molecular system and for developing medical, pharmaceutical, and other practical applications. Since 1995 we have been developing knowledge-based methods for uncovering higher-order systemic behaviors of the cell and the organism from genomic and molecular information. The users can access the KEGG API server by the SOAP technology over the HTTP protocol. The SOAP server also comes with the WSDL, which makes it easy to build a client library for a specific computer language. (WSDL, SOAP)
![]()
arXiv API
http://arxiv.org/help/api/index
Rajapinnan englanninkielinen kuvaus: Allows access to all of the arXiv data, search and linking facilities. The Cornell University e-print arXiv, hosted at arXiv.org, is a document submission and retrieval system used by the physics, mathematics and computer science communities. It has become the primary means of communicating manuscripts on current and ongoing research. The arXiv repository is available worldwide. Manuscripts are often submitted to the arXiv before they are published by more traditional means. In some cases they may never be submitted or published elsewhere. The purpose of the arXiv API is to allow programmatic access to the arXiv's e-print content and metadata. The goal of the interface is to facilitate new use of the the vast body of material on the arXiv. (REST)
![]()
Wolfram API
http://www.wolframalpha.com/developers.html
Rajapinnan englanninkielinen kuvaus: The API provides two general classes of queries. At the highest level, you can submit free-form queries like users might enter at the Wolfram|Alpha site itself, and get back full Wolfram|Alpha output in a variety of formats. The second type of query is a lower-level request for a single well-defined result, or range of results, from their entity/property-based data API, such as a caloric value for a food item, or a tide table for a requested location. (REST)
![]()
NCBI Entrez API
http://www.ncbi.nlm.nih.gov/entrez/query/static/eutils_help.html
Rajapinnan englanninkielinen kuvaus: The NCBI Entrez Utilities Web Service enables developers to access U.S. National Library of Medicine databases’ bioinformatics data. (WSDL, SOAP, REST)

Reittiopas-API
http://developer.reittiopas.fi/pages/fi/reittiopas-api.php
Rajapinnan kuvaus: YTV tarjoaa Reittioppaan rajapinnan
käyttöoikeutta tuotekehitys- ja testauskäyttöä varten, mikäli kehitettävä
ohjelmisto tai palvelu edistää joukkoliikennettä ja matkustajainformaation
saatavuutta. (REST, XML dump)

REST-tyylinen palvelu koostuu asiakkaista ja palvelimista, pyyntöjen ja vastausten voidessa koostua mistä tahansa, minkä tietyllä merkistökoodauksella voi ilmaista. Pyynto voi olla vaikkapa yksittäinen sana, jolla saadaan palvelimelta vastauksena esim. XML-dokumentti, joka sisältää jonkin taginsa sisällä 256-värisen 32x32-kokoista kuvaikonia kuvaavan merkkijonorimpsun. Rimpsu voisi esiintyä myös ilman XML-dokumenttia tai olla käärittynä JSON-puuhun. Tai voisi olla niinkin päinä, että rimpsu olisi se, joka lähetetään palvelimelle ja vastauksena saataisiin yksittäinen sana. Se mitä asiakassovellus tekisi tuolle sanalle olisi tietenkin täysin mielivaltaisesti päätettävissä.
Olennaisiin piirteisiin kuuluu se, että kaikki resurssit ovat saatavilla yhtenäisen yleisen rajapinnan kautta (HTTP GET, POST, PUT, DELETE). Yhteistä näillä on kohdeosoitteen vaatimus (Request-Uri). GETin ja POSTin ero on siinä, että ensin mainitussa metodissa kutsu osoitteineen ja kutsun sisältöineen ilmaistaan osoitteessa itsessään. POST-metodissa data sisältyy kutsun runko-kenttään (Body). Ohjelmallisesti tehtäessä mukana lähetetään myös tietyt otsikkotiedot (Header), joista eräs kertoo palvelimelle saapuvan tiedon tyypin (esim. text/html).
GET-tyyppinen kutsu voisi olla esim. tälläinen:
http://data.gbif.org/ws/rest/network/list?name=biological
Tuo palauttaisi REST-tyyppistä API:a käyttävästä liittymästä metatietoa tiettyyn verkostoon liitetyistä dataseteistä. APIn dokumentaatio löytyy osoitteesta: http://data.gbif.org/ws/rest/network
Muita RESTin piirteitä (Costello):
- Nimetyt resurssit: jokainen resurssi on yksikäsitteisesti tunnistettavissa ja viitattavissa, mutta resurssilla voi olla useitakin osoitteita, jotka viittaavat siihen
- Tilaton: jokainen viesti asiakkaalta sisältää kaiken informaation, joka pyynnön käsittelemiseksi tarvitaan, eikä aiemmin viestittyyn voida viitata
- Välimuisti: vastaukset täytyy voida merkitä välimuistitettavissa oleviksi eli saman pyynnön uudelleenlähettäminen ei aiheuttaisi uutta kutsua palvelimella, vaan käytettäisiin jo välimuistissa olevaa vastausta
HKL:n ajoneuvojen sijainnit (Javascript)
Palvelu Helsingin Kaupungin Liikennelaitoksen (HKL) eli ilmeisestikin tulevan (Helsingin kaupunki 2009) Helsinkin Seudun Liikenteen (HSL) liikennöintivälineiden reaaliaikaseurantaan:

Palvelu osoitteessa: http://transport.wspgroup.fi/hklkartta/
Last on AM/FM (Flash)
Localizes the artists for different radio stations. A mashup made with Yahoo Pipes, youTube, freebase, Twitter, last.fm, Yahoo Maps, Google Maps, Google App Engine, Wikipedia..

Palvelu osoitteessa: http://www.cs.kuleuven.be/~sten/lastonamfm/
Tianamo (Java)
Tianamo uses Java to plot search keywords on a dynamically-generated 3D terrain. Clicking on the terrain will let you navigate through related topics while search results are displayed on the right. Hakee tiedot Yahoosta.

Palvelu osoitteessa: http://search.tianamo.com/index2.php
Demo YouTubessa: http://www.youtube.com/watch?v=2i4Njh1w8DU
Nooblast (Flash)
Project picks the real-time data for two given keywords from public APIs and visualizes around the globe as "noo"-cloud, the size of which reflects event streams and shaped by geo data, building light abstract visual structures in space for each. picks the real-time data from variety of public APIs and calculates overall strength of signal for two given keywords, which then visualized around the globes as "noo"-cloud.

Palvelu osoitteessa: http://pavelrisenberg.com/interactive/nooblast/
Demo Vimeossa: http://www.vimeo.com/5624108
Alkuperäisessä merkityksessään AJAX:lla (akronyymi sanoista Asynchronous JavaScript And XML) on alunperin viitattu tekniikkaan, jossa verkkosivulla Javascriptillä asynkronisesti tehtävistä REST-tyylisistä pyynnöistä (GET, POST) palautetaan XML-merkkausta. Nykyisin Ajax-tekniikoilla viitataan samankaltaiseen toimintatapaan, mutta ilman erityisvaatimusta palautuvan datan olemiselle XML-muotoista. Ajaxissa (kirjoitetaan kuten erisnimi, isolla alkukirjaimella) selainohjelma vaihtaa pieniä määriä dataa palvelimen kanssa taustalla niin, ettei koko verkkosivua tarvitse ladata uudelleen joka kerta käyttäjän tehdessä muutoksen. Tekniikan päämääränä on siis lisätä verkkopalvelun vuorovaikutteisuutta, nopeutta ja käytettävyyttä.
Ajax-pyynnön voi tehdä vaikeamman kautta eli tarkistaa samalla kaikki eri selainten puutteet ja tiettyjen toimintojen tukemiset tai sitten helpomman kautta eli hyödyntämällä jotain sopivaa Javascript-kirjastoa kuten jQueryä.
Helpomman kautta:
$("#feeds").load("feeds.html"); |
Eräs työteliäämpi tapa (Developer Connection 2005):
function loadXMLDoc(url) { req = false; // branch for native XMLHttpRequest object if (window.XMLHttpRequest && !(window.ActiveXObject)) { try { req = new XMLHttpRequest(); } catch (e) { req = false; } // branch for IE/Windows ActiveX version } else if (window.ActiveXObject) { try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { req = false; } } } if (req) { req.onreadystatechange = processReqChange; req.open("GET", url, true); req.send(""); } } |
Tavallisesti pyyntö on rajoitettu siihen palvelimeen, josta websivu, jossa kutsuva skripti sijaitsee, mutta tämän kiertämiseen on erilaisia hack-tyyppisiä ratkaisuja ja tulevaisuudessa myös joitakin virallisempia (W3C-organisaatio on tehnyt ehdotuksen Access Control for Cross-Site Requests -suositukseksi), jota webselaimista ainakin Firefox 3.5 tukee (Mozilla Developer Center 2008). Tämä rajoitus pätee kuitenkin vain siihen mihin webselaimessa ajatteva Javascript-koodi pystyy ottamaan yhteyttä. Yleensä toimitaankin niin, että lähetetään käsky palvelimelle ottaa yhteys johonkin ulkoiseen palveluntarjoajaan ja haetaan tieto sitä kautta. Webpalvelimella ei ole samanlaista kiinteää rajoitusta sille mistä se voi tietoa hakea, ellei sitä ole konfiguraatiotiedostoissa erikseen määritelty.
EMML (Enterprise Mashup Markup Language) on XML-merkintäkieli enterprise-tason mashuppien luomiseen. Ne yhdistelevät ja uudelleenmixaavat data tietokannoista, taulukoista, websivustoilta, webpalveluista, tietovirroista ja jäsentelemättömistä lähteistä (Open Mashup Alliance 2009) käyttäen yhtenäistä syntaksia kutsuakseen palvelutyyppejä: REST, WSDL, RSS/ATOM, RDBMS, and POJO. EMML-kieli mahdollistaa erityyppisten dataformaattien (XML, JSON, JDBC, JavaObjects ja primitiiviset tietotyypit) yhdistelemisen.
Käytännössä tarvitaan jokin J2EE-yhteensopiva ohjelmistopalvelin, johon asennetaan EMML Reference Runtime Engine. Alla oleva kuva ilmentää joitakin olennaisimpia ominaisuuksia (Alur 2009).

Kuva 8. EMML:n avainominaisuuksia
Internetguru Dion Hinchliffen, jonka yritys on Open Mashup Alliancen (OMAn) perustajataho, blogissa oli seuraava kuva, joka selventää (Hinchcliffe 2009) asioiden toisella tapaa.

Kuva 9. EMML:lää selventävä kuva
Consequently part of the power of EMML is that it ultimately decouples mashups from the browser and brings the approach to a much broader set of situations in the enterprise and beyond. (Hinchcliffe 2009)
Kaikki seuraavat poiminnot ovat EMML sample code -paketista, joka on saatavilla osoitteessa:
http://www.openmashup.org/download/download.html
EMML
<mashup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xsi:schemaLocation="http://www.openemml.org/2009-04-15/EMMLSchema ../schemas/EMMLSpec.xsd" xmlns="http://www.openemml.org/2009-04-15/EMMLSchema" name="TestService"> |
REST
<input name="query" type="string" default="cricket" /> <output name="searchResults" type="document" /> <directinvoke endpoint="http://boss.yahooapis.com/ysearch/news/v1/{$query}" appid=".kcC72DV34FYTpAGuwwbV8YGI.DsMBQ0RB9eZARS621ecnHq33c.g1XJV93a64hrdaM3" format="xml" outputvariable="search" /> |
SQL
<sql query="select min(CREATED) from AUDITABLE_EVENT where SERVICE_ID = :serviceId" outputvariable="dt" /> |
XSLT
<xslt script="{$stylesheet}.xsl" inputvariable="dataset1" outputvariable="result" /> |
FOREACH-LOOP
<foreach variable="itm" items="distinct-values($feed//author/@name)"> <display message="author = " expr="$itm"/> |
FILTER
<filter inputvariable="jobsDoc" filterexpr="/rss/channel/item[matches({$filterCriteria}, $filterData)]" outputvariable="jobsDoc" /> |
XPATH
<display message="sample expr3 = ...." expr="$groupedResult//author[3]/@name/string()" /> |
PARALLER QUERIES
<parallel> <sequence> <directinvoke endpoint="http://search.yahooapis.com/ContentAnalysisService/V1/termExtraction" method="post" appid="$appId" context="$searchText" query="$query" timeout="10" onerror="continue" outputvariable="keywords" /> |
SOAP
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"> <soap:Header> {$soapHeader} </soap:Header> <soap:Body> {$soapBody} </soap:Body> </soap:Envelope> |

XML 1.0 (Extensible Markup Language) on ”laajennettavissa oleva merkkauskieli”. XML on perusluonteeltaan metakieli, eikä esim. valmiiksi sisällä yhdenkään elementin määrittelyä. Merkkauksen semantiikka jää sitten yksittäisten XML-sovellusten tehtäväksi. Keskeisten ”yleishyödyllisten” XML-sovellusten sanastoja ja semantiikka (esim. skeemat, hyperteksti ja tyylit) standardoidaan kuitenkin keskitetysti W3C:n XML-standardiperheen puitteissa. (Nykänen 2004)
XML-dokumentin sanotaan olevan hyvinmuodostettu (en. well-formed), jos sen tageista muodostuva rakenne on puumuotoinen, eikä mitään sisältöä ole tagien ulkopuolella tai väleissä. Lisäksi mm. seuraavien ehtojen täytyy täyttyä:
- Dokumentissa on tasan yksi juurielementti. (seuraavassa esimerkissä juurielementti on ostoskori)
- Perus-ASCII -merkistöön kuulumattomat merkit ovat asianmukaisesti koodattuja. (Unicode-merkistössä eräs kiinankielinen merkki voidaan kirjoittaa joko 中 tai 中)
- Elementeillä, myös tyhjillä on sekä alku- että lopputagit. (tyhjät elementit voidaan lyhentää muotoon <selite />)
- Jokainen attribuutti on lainausmerkkien sisällä.
Yksinkertaisimpia esimerkkejä XML-dokumentista olisi vaikkapa seuraava:
<?xml version="1.0"?> <ostoskori> <tuote koodi="001">omena</tuote> <tuote koodi="002">porkkana</tuote> </ostoskori> |
Ensimmäisen rivin jälkeen voidaan liittää viite ulkopuoliseen dokumentin tyyppimääritystiedostoon, jonka tarkoitus on pakottaa XML-dokumentti noudattamaan tiettyä rakennetta ja määritettyjä ehtoja (esim. monilukuisuus). Riippuu XML-sovelluksesta tai käytetystä API:stä, käyttääkö se tätä pakotetta ja täten testaa onko dokumentti validi määrityksen suhteen.
Dokumentin tyyppimäärityksen voi toteuttaa useillakin erilaisilla standardimuotoisilla määrityksillä, joka siis rajaa sen, mitkä ovat tietyssä XML-dokumentissa sallitut elementtien ja attribuuttien ilmenemismuodot. Eräs näistä on DTD (Document Type Defination).
Sisällytettäessä DTD-määritys XML-dokumenttiin (voitaisiin asettaa myös ohjelmallisesti), seuraava rivi täytyisi lisätä edellisen XML-dokumentin sisältävän tiedoston toiseksi riviksi:
<!DOCTYPE ostoskori SYSTEM "Untitled1.dtd">
DTD-tiedosto voisi näyttää esim tältä:
<?xml encoding="UTF-8"?>
<!ELEMENT ostoskori (tuote)+> <!ATTLIST ostoskori xmlns CDATA #FIXED ''>
<!ELEMENT tuote (#PCDATA)> <!ATTLIST tuote xmlns CDATA #FIXED '' koodi CDATA #REQUIRED> |
Eräs toinen vaihtoehto tyyppimäärityksille on käyttää DTD:n sijaan XML Schemaa. Se vaatisi korvaamaan dokumentin juurielementin sisältämään viittaukset seuraaviin:
<ostoskori xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Untitled1.xsd"> |
XML Schema -tiedosto voisi näyttää tälläiseltä:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="ostoskori"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" ref="tuote" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="tuote"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:NCName"> <xs:attribute name="koodi" use="required" type="xs:integer" /> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> </xs:schema> |
Erityistä huomioitavaa tässä ovat attribuuttien tietotyyppimääritykset, joista tässä esimerkkinä vaatimus koodi-attribuutin olemiselle integer-tyyppinen. Tätä ei voitaisi toteuttaa DTD:llä.
Jos haluaisimme muuntaa alkuperäisen XML-dokumentin esim. HTML-standardin mukaiseksi, voisimme käyttää XSLT-tyylisivua (Extensible Stylesheet Language Transformations) tämän toteuttamiseksi vaikkapa seuraavanlaisesti:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output method="html" encoding="iso-8859-1" indent="yes" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
<xsl:template match="ostoskori"> <xsl:element name="html"> <xsl:element name="head"/> <xsl:element name="body"> <xsl:element name="ul"> <xsl:for-each select="tuote"> <xsl:element name="li"> <xsl:value-of select="@koodi"/> </xsl:element> </xsl:for-each> </xsl:element> </xsl:element> </xsl:element> </xsl:template>
</xsl:stylesheet> |
XSLT mahdollistaa samasta alkuperäisdokumentista (XML-dokumentti) johdettavan useita erilaisia transformoituja versioita.
Käytettynä alkuperäiseen XML-tiedostoon tulostuisi seuraavanlainen HTML-tiedosto:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body> <ul> <li>001</li> <li>002</li> </ul> </body> </html> |
Erityyppisten (X)HTML-tiedostojen doctypejä (aina ensimmäinen rivi, tiedoston tyypin määrittelevä rivi) voi tarkastella esim. W3Schoolsin sivuilta: http://www.w3schools.com/tags/tag_DOCTYPE.asp
Sen dokumentin kannalta, jota parhaillaan luet, on olennaista käsitellä vielä yksi olennaisuus, joka on XPath. Se on tarkoitettu XML-dokumentin elementteihin viittaamiseen. XPath-kieli (XML Path Language) perustuu XML-dokumentin puumuotoiseen esitystapaan ja antaa siten mahdollisuuden poimia osia dokumentista tietyillä valintakriteereillä. Jo esillä olleesta XML-dokumentistamme voi tehdä esim. seuraavanlaisia hakuja:
//ostoskori/tuote (kaikki tuote-nimiset
haaraumat ostoskori-polusta)
//ostoskori/tuote[1] (vain ensimmäinen tuote-niminen
haarauma)
//ostoskori/tuote/@koodi (kaikki tuote-nimisten
haaraumien koodi-nimiset attribuutit)
//ostoskori/tuote[@koodi=002] (vain tuote, jonka attribuutin koodi arvo on 002)
//ostoskori/tuote[round-half-to-even(number("1.6"))] (porkkana)
Nyt kun XML:n perusteita on hiukan sivuttu ja ehditty tutustua XSL-tyylisivuihin ja XPathiin, onkin hyvä hetki karistella turhia luuloja pois mielestään ja ottaa käsiteltäväksi jotain, jonka ymmärtäminen on periaatteessa helppoa, mutta vaatii käytännössä paljon perehtymistä.
Adobe InDesignin CS4-versio pystyy binäärimuotoisten tiedostomuotojen lisäksi tallettamaan dokumentit myös XML-pohjaiseen muotoon, IDML:läksi. Kyseiseen muotoon InDesignistä talletettaessa tullaan itseasiassa luoneeksi ZIP-pakattu tiedosto, joka sisältää kansiorakenteen, joihin kuhunkin on ripoteltu joukko XML-tiedostoja. Osa näistä tiedostoista määrittelee sisältöä, osa asettelua, osa metatietoa ja osa jotain muuta. Seuraavassa on muutama ote näiden tiedostojen sisällöistä, alla olevan kuvan mukaiselle dokumentille.

Kuva 10. Yksinkertainen InDesign-dokumentti.
Koska IDML-muotoisen InDesign-dokumentin muodostavat XML-tiedostot (enimmäkseen), voi tiedostoa muokata ja siitä hakea tietoa myös muiden työvälineiden avulla tai käsitellä niitä esim. XSLT:lällä.
designmap.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?aid style="50" type="document" readerVersion="6.0" featureSet="257" product="6.0(578)" ?> <Document xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging" DOMVersion="6.0" Self="d" StoryList="ucf u9b" ZeroPoint="0 0" ActiveLayer="ub6" CMYKProfile="Coated FOGRA27 (ISO 12647-2:2004)" RGBProfile="sRGB IEC61966-2.1" SolidColorIntent="UseColorSettings" AfterBlendingIntent="UseColorSettings" DefaultImageIntent="UseColorSettings" RGBPolicy="PreserveEmbeddedProfiles" CMYKPolicy="CombinationOfPreserveAndSafeCmyk" AccurateLABSpots="false"> |
Story_ucf.xml
<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/listatyyli"> <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]"> <Content>omena</Content> <Br /> <Content>porkkana</Content> </CharacterStyleRange> </ParagraphStyleRange> </Story> |
Styles.xml
<ParagraphStyle Self="ParagraphStyle/listatyyli" Name="listatyyli" Imported="false" NextStyle="ParagraphStyle/listatyyli" KeyboardShortcut="0 0" BulletsAndNumberingListType="BulletList"> <Properties> <BasedOn type="string">$ID/[No paragraph style]</BasedOn> <PreviewColor type="enumeration">Nothing</PreviewColor> <TabList type="list"> <ListItem type="record"> <Alignment type="enumeration">LeftAlign</Alignment> <AlignmentCharacter type="string">.</AlignmentCharacter> <Leader type="string"></Leader> <Position type="unit">14.173228346456694</Position> </ListItem> </TabList> </Properties> </ParagraphStyle> |
Spread_ub9.xml
<Spread Self="ub9" PageTransitionType="None" PageTransitionDirection="NotApplicable" PageTransitionDuration="Medium" FlattenerOverride="Default" ShowMasterItems="true" PageCount="1" BindingLocation="0" AllowPageShuffle="true" ItemTransform="1 0 0 1 0 0"> <FlattenerPreference LineArtAndTextResolution="300" GradientAndMeshResolution="150" ClipComplexRegions="false" ConvertAllStrokesToOutlines="false" ConvertAllTextToOutlines="false"> <Properties> <RasterVectorBalance type="double">50</RasterVectorBalance> </Properties> </FlattenerPreference> |
HL7 viittaa sekä organisaatioon, joka kehittää ja tukee terveydenhuollon standardeja, joiden on tarkoitus mahdollistaa erilaisten terveydenhuollossa käytettyjen ohjelmistojen yhteentoimivuus datan jakamisen ja kommunikoinnin osalta, että se viittaa myös kehittämiin ja ylläpitämään standardeihin kuten HL7 v3 messaging ja HL7 v3 Clinical Document Architecture (CDA).
Tarve yhtenäiselle terveydenhuoltoon liittyvien dokumenttien määrittelylle ja eri järjestelmien/ohjelmistojen välisen viestinnän standardoimiselle on ymmärrettävää, sillä ilman niitä sama tieto kertyy tarpeettomasti useaan tietokantaan, samoja tietoja joudutaan kirjaamaan useita kertoja eri järjestelmiin, eri sovellukset vaativat oman kirjautumisensa, eivätkä ohjelmistojen rajapinnat ole olleet keskenään yhteensopivia.
Given that HL7 defines a messaging as a well as a document standard, which have the ability to convey more or less the exact same data: when should one use messaging and when would the use of documents be more appropriate? (Spronk 2007)
HL7:ssa termistössä dokumentit ovat luonteeltaan pysyviä, staattista sisältöä sisältäviä kokonaisuuksia, ollen sekä ihmisten, että koneiden luettavissa. Viestit on tarkoitettu koneellisesti prosessoitavaksi ja tukemaan meneillään olevaa prosessia reaaliaikaisesti.
Tiedon talletusmuoto HL7 messaging standardin versiossa 2 oli vielä taulukkodataa:

HL7 messaging standardin versiossa 3 muodoksi oli ilmeisen hyvästä syystä valittu yleisesti käytössä oleva XML-merkkauskieli:

Kuva 11. HL7 messaging standardin versioiden 2 ja 3 ilmiselvin ero.
HL7v3-viestit kääräistään useampaan pakettiin, joiden tarkoituksena on tukea tietoturvallisuutta, tiedonsiirron varmuutta ja kohdistamista (Graauw 2005).

Kuva 12. HL7 v3 Message -malli
Tosielämän esimerkki HL7-standardin käytöstä: NiceWatch Enterprise Business Connector with HL7 support is a centralized global messaging and label printing middleware software that integrates printing of wristband, charts and admittance forms into Healthcare Information System (HIS), Laboratory Information System (LIS), Pharmacy Information System (PIS) applications and others. (Niceware Healthcare 2009)
Kyseisen toimijan viestintärajapinta mahdollistaa terveydenhuollon, vakuutuksen lisäpalveluita tarjoavien instituutioiden ja ohjelmistojen kommunikoida keskenään yhteisellä kielellä. Käyttäen HL7-viestinnän noudattaminen mahdollistaa sairaaloiden yksinkertaistaa potilaiden pääsyä, tunnistamista, poislaskemista, laboratoriomääräyksiä ynnä muuta sellaista.

Kuva 13. NiceWatch Enterprisen HL7 Message –hyödynnös.
Seuraavassa esimerkissä käytetään DOM4J -Java-kirjastoa XML-tiedoston käsittelyyn - koska se on sillä niin verrattoman kätevää. Tiedosto, josta tietoa haetaan näyttää tälläiseltä (otos Wordnet-tietokannan sisällöstä eräässä XML-muodossa):
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="sample-definition.xsl"?> <definitions> <row definition="a small vessel for travel on water" lemma="boat"/> <row definition="a dish (often boat-shaped) for serving gravy or sauce" lemma="boat"/> <row definition="ride in a boat on water" lemma="boat"/> <row definition="a lump or mass of hard consolidated mineral matter" lemma="rock"/> <row definition="pitching dangerously to one side" lemma="rock"/> <row definition="the range of interest or activity that can be anticipated" lemma="view"/> <row definition="outward appearance" lemma="view"/> </definitions> |
import java.io… import java.util… import javax.xml.transform… import org.dom4j…
class DOM4JParser {
String testMethod() {
String output = null; String sourcePathXSL = "resources/"; String sourcePathXML = "resources/"; String sourceFilenameXSL = "sample-definition-xslt1.xsl"; String sourceFilenameXML = "sample-definition.xml";
// System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "net.sf.saxon.om.DocumentBuilderFactoryImpl"); // System.setProperty("javax.xml.xpath.XPathFactory:" + NamespaceConstant.OBJECT_MODEL_SAXON, "net.sf.saxon.xpath.XPathFactoryImpl"); // System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = null; try { transformer = factory.newTransformer(new StreamSource(new File(sourceFilenameXSL))); } catch (TransformerConfigurationException ex) { Logger.getLogger(DOM4JParser.class.getName()).log(Level.SEVERE, null, ex); } |
Käytöstä pois on kommentoituna Saxonica-merkkinen XML-parseri. Seuraavassa vaiheessa koodia luodaan lukija ja luetaan lukijaan sisältöä tiedostosta.
SAXReader reader = new SAXReader(); Document document = null;
try { document = reader.read(sourceFilenameXML); } catch (DocumentException ex) { Logger.getLogger(DOM4JParser.class.getName()).log(Level.SEVERE, null, ex); } |
Tämän jälkeen luettua dokumenttia voisi muokatakin, seuraavissa kolmessa käsittelytavassa sitä vain luetaan. Ensinnä haetaan (ilman XPathia) ensimmäisten solmukohtien kaikki sellaiset attribuutit, joiden nimi on ’definition’ ja talletetaan tämä List-rakenteeseen.
// Nodes and attributes
Element root = document.getRootElement();
List<String> definition = new ArrayList<String>(); for (Iterator i = root.elementIterator(); i.hasNext();) { Element element = (Element) i.next(); for (Iterator j = element.attributeIterator(); j.hasNext();) { Attribute attribute = (Attribute) j.next(); String t = attribute.getText(); if (attribute.getName().equals("definition")) { definition.add(attribute.getValue()); } } } |
Seuraavaksi haeskellaan XPathilla
useampaan otteeseen:
// XPathing
List list = document.selectNodes("//row"); Node node = document.selectSingleNode("//row[1]"); String name = node.valueOf("@definition");
List lemmaAttrNodes = document.selectNodes("//row/@lemma"); List<String> lemma = new ArrayList<String>(); for (Iterator iter = lemmaAttrNodes.iterator(); iter.hasNext();) { Attribute attribute = (Attribute) iter.next(); lemma.add(attribute.getValue()); } |
Ja tehdään XSLT-muunnos:
// XSL-transformation
DocumentSource source = new DocumentSource(document); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); transformer.setOutputProperty(OutputKeys.METHOD, "text"); transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
StringWriter sw = new StringWriter(); StreamResult sr = new StreamResult(sw); try { transformer.transform(source, sr); } catch (TransformerException ex) { Logger.getLogger(DOM4JParser.class.getName()).log(Level.SEVERE, null, ex); } String transformOutput = sw.toString();
return transformOutput;
} } |
Työnkulussa voisi XML-dokumentin olemassaoloa edeltää joukko relaatiotietokannan tauluja, joista hakutuloksena saatu tieto muunnetaan XML-muotoiseksi. Esimerkkinä yksittäisen Fineli-ravintotietokannan ruokanimike-taulun suhde vastaavaan XML-rakenteeseen:

Kuva 14. Tietokannan taulun suhde vastaavansisältöiseen XML-tiedostoon.
CORBA (Common Object Request Broker Architecture) on standardi arkkitehtuuri hajautettujen objektien järjestelmille, joka sallii heterogeenisen kokoelman objekteja toimia yhteen. Palvelut, joita objekti tarjoaa, jaellaan sen rajapinnan kautta. Rajapinnat on määritelty IDL:llä (Interface Definition Language).
Alla oleva kuva (jGuru.com 1999) esittää asiakaspuolen lähettämää pyyntöä. Asiakkaalla on viite hajautettuun objektiin, joka on määritelty sen rajapinnalla. ORB (Object Request Broker) välittää pyynnön objektille ja palauttaa mahdollisen vastauksen asiakkaalle.

Kuva 15. Asiakkaan lähettämä, ORB:n kautta kulkeva, pyyntö CORBA-arkkitehtuurissa.
ORB on hajautettu palvelu, joka toteuttaa pyynnön, joka on kohdistettu etäobjektille. Etäobjektin sijainnin se osaa etsiä verkosta, eikä asiakkaan tarvitse tietää missäpäin etäobjekti varsinaisesti sijaitsee. Erityisesti on huomioitavaa, että ORB toteuttaa ohjelmointikieliriippumattomuuden pyynnölle. Pyynnön lähettämä asiakassovellus voi olla kirjoitettu aivan eri ohjelmointikielellä kuin etäobjekti. ORB tekee tarpeellisen käännöstyön ohjelmointikielien välillä -- ainakin tunnetuimpien niistä:
Using the standard protocol IIOP, a CORBA-based program from any vendor, on almost any computer, operating system, programming language, and network, can interoperate with a CORBA-based program from the same or another vendor, on almost any other computer, operating system, programming language, and network. (OMG 2009)
ebXML on joukko spesifikaatioita, jotka yhdessä mahdollistavat modulaarisen elektronisen kaupankäynnin ohjelmistokehyksen. ebXML:n visiona on mahdollistaa maapallon laajuinen elektroninen markkinapaikka, jossa minkä tahansa kokoiset ja missäpäin tahansa sijaitseva yritykset voivat tavata ja johtaa yritysoimintaa keskenään XML-pohjaisten viestien välityksen kautta. (OASIS Open 2006)
Toisin sanoen, ebXML seurata EDI:n (Electronic Data Interchange) menestystä (Merz 2001).

Kuva 16. Interaktio kahden yrityksen välillä
Liiketoimintaprosessit ovat organisaatioiden fundamentaalisia toimintoja. Esimerkkeinä liiketoimintaprosesseista ovat hyödykkeiden tai palveluiden ostaminen, hyödykkeiden lähetys, laskun maksaminen ja sopimusten neuvotteleminen (Walmsley 2001).
RosettaNet standardit ja palvelut tarjoavat yhteisen kielen e-liiketoimintapahtumille ja perustan kriittisten prosessien integroimiseen maapallon laajuisen partnereiden muodostaman toimitusketjun välillä. Yritykset, jotka käyttävät RosettaNetin toimivaksi todettuja standardeja hyötyvät lisäarvosta kulusäästöjen muodossa, jotka ilmentyvät toimitusketjun prosesseissa, parantuneessa e-liiketoimintaviestinnässä kauppaa käyvien partnereiden välillä, paranneltu tuotteiden elinkaaren hallintatoiminnallisuus, sekä lisääntynyt asiakastyytyväisyys. (RosettaNet)
Käyttäjiä, Itella: Itellan ratkaisu sisältää tuen kaikille RosettaNet-yhteyksien vaatimille standardeille. Itellan ratkaisussa käytetään RNIF (RosettaNet Implementation Framework) -määritysten mukaisia komponentteja, joiden avulla tarvittavat standardoidut PIP™ (Partner Interface Process) -prosessit toteutetaan. Osapuolien tunnistamisessa käytetään yksilöiviä DUNS® -numeroita, jolloin tunnistamisen määrittely ei aiheuta ongelmia. Tiedostomuotona voidaan käyttää mitä tahansa asiakkaan järjestelmän muodostamaa formaattia. Loogisinta on käyttää sovelluksen omaa sisäistä esitystapaa eli inhouse-muotoa, jolloin mitään keinotekoisia väliformaatteja ei tarvita. Itella voi tulkita käytännössä mitä tahansa esitystapaa. Sanomasisällöissä huomioidaan UN/SPSC- ja GTIN-artikkelien luokittelut ja numeroinnit. Asiakkaan kumppanin suuntaan voidaan käyttää sanomarakenteena standardoituja XML-formaatteja. (Itella)
Käyttäjiä, Nokia: RosettaNetin perusajatuksena on avoimuus ja se pyrkii edistämään RosettaNetiin liittyvien yritysten välistä vuoropuhelua ja kokemusten jakamista RosettaNet standardin käyttöönotosta. Nokia on RosettaNetin voimakas puolestapuhuja. Se on valinnut RosettaNetin standardikseen integroidessaan omaa toimitusketjuaan ja valmistelee laajempaa käyttöönottoa globaalisti. Suuret elektroniikkateollisuuden yritykset ovat vahvasti mukana RosettaNetin toiminnassa. Toimintaa pyritään laajentamaan myös muiden toimialojen, kuten autoteollisuuden piiriin. (Tekes)
Internet (henkilöitävät)
Alur, Deepak 2009. OMG! We launched OMA and EMML. The Enterprise Web 2.0 Blog. Luettu 7.11.2009. Saatavilla: http://blogs.jackbe.com/2009/09/omg-we-launched-oma-and-emml.html
Costello, Roger. Building Web Services the REST Way. Luettu 7.11.2009. Saatavilla: http://www.xfront.com/REST-Web-Services.html
Graauw, Marc de 2005. Implementing Web Services in Dutch Healthcare. Ringholm GmbH. Luettu 7.11.2009. Saatavilla: http://www.ringholm.de/docs/03030_en.htm
Hicks, Terry 2002. WS-I Rejects Sun, Fires First Shot in Web Standards War. Gartner. Luettu 7.11.2009. Saatavilla: http://www.gartner.com/resources/106300/106382/106382.pdf
Hinchcliffe, Dion 2009. Creating a unified model for enterprise mashups. Luettu 7.11.2009. Saatavilla: http://blogs.zdnet.com/Hinchcliffe/?p=872
Merz, David 2001. Understanding ebXML. IBM. Luettu 7.11.2009. Saatavilla: http://www.ibm.com/developerworks/xml/library/x-ebxml/
Nickull D., Reitman L.,Ward J & Wilber J. 2007. Service Oriented Architecture (SOA) and Specialized Messaging Patterns. Adobe. Luettu 7.11.2009. Saatavilla: http://www.adobe.com/enterprise/pdfs/Services_Oriented_Architecture_from_Adobe.pdf
Ojanperä, Veijo 2001. Nokia ja Philips ottivat RosettaNetin käyttöön. Prosessori. Luettu 7.11.2009. Saatavilla: http://www.prosessori.fi/uutiset/uutinen2.asp?id=41518
Raghu, Kodali 2005. What is service-orientated architecture? JavaWorld. Luettu 7.11.2009. Saatavilla: http://www.javaworld.com/javaworld/jw-06-2005/jw-0613-soa.html
Spronk, Rene 2007. HL 7 version 3: Message or CDA Document?. Ringholm GmbH. Luettu 7.11.2009. Saatavilla: http://www.ringholm.de/docs/04200_en.htm
Wong, Wylie 2002. Microsoft ploy to block Sun exposed. CNET News. Luettu 7.11.2009. Saatavilla: http://news.cnet.com/Microsoft-ploy-to-block-Sun-exposed/2100-1002_3-912906.html
Walmsley, Priscilla 2001. ebXML: An Overview . InformIT. Luettu 7.11.2009. Saatavilla: http://www.informit.com/articles/article.aspx?p=24013&seqNum=4
Internet (organisaatio- ja yrityssivustot)
CDBI 2005. Web Services Protocols Summary. Luettu 7.11.2009. Saatavilla: http://roadmap.cbdiforum.com/reports/protocols/summary.php
Cover Pages 2002. Sun Microsystems Joins WS-I - Web Services Leader Plans to Run for Board Election. Luettu 7.11.2009. Saatavilla: http://xml.coverpages.org/SunJoinsWSI.html
Developer Connection 2005. Dynamic HTML and XML: The XMLHttpReqest Object. Luettu 7.11.2009. Saatavilla: http://developer.apple.com/internet/webcontent/xmlhttpreq.html
jGuru.com 1999. Introduction to CORBA. Sun Developer Network. Luettu 7.11.2009. Saatavilla: http://java.sun.com/developer/onlineTraining/corba/corba.html
GBIF 2009. The Global Biodiversity Resources Discovery System (GBRDS). Luettu 7.11.2009. Saatavilla: http://www.slideshare.net/vishwaschavan/gbrds-summary-final-july2009-2
IBM 2003. Web Services Policy Framework. Luettu 7.11.2009. Saatavilla: http://www.ibm.com/developerworks/library/specification/ws-polfram/
Helsingin kaupunki 2009. HSL aloittaa 1.1.2010. Luettu 7.11.2009. Saatavilla: http://www.hel.fi/wps/portal/HKL/Artikkeli?WCM_GLOBAL_CONTEXT=/hkl/fi/HKL-tietoa/Helsingin+seudun+liikennekuntayhtyma
Itella. ItellaXML for RosettaNet – Teknologia. Luettu 7.11.2009. Saatavilla: http://www.itella.fi/palvelutjatuotteet/isupplychain/itellaxml/xmlforrosettanet/teknologia.html
Microsoft 2005. UBR Shutdown FAQ. Luettu 7.11.2009. Saatavilla: http://uddi.microsoft.com/about/FAQshutdown.htm
Microsoft 2002. Industry Leaders Align Around Web Services Interoperability. Luettu 7.11.2009. Saatavilla: http://www.microsoft.com/presspass/press/2002/feb02/02-06InteropOrgPR.mspx
Mozilla Developer Center 2008. HTTP access control. Luettu 7.11.2009. Saatavilla: https://developer.mozilla.org/En/HTTP_access_control
MSDN 2009. WS-Management Protocol. Luettu 7.11.2009. Saatavilla: http://msdn.microsoft.com/en-us/library/aa384470%28VS.85%29.aspx
Niceware Healthcare 2009. NiceWatch Enterprise Business Connector (HL7 Interface). Luettu 7.11.2009. Saatavilla: http://healthcare.nicewareintl.com/cgi-bin/site.pl?3208&dwContent_contentID=80
OASIS 2004. UDDI Version 3.0.2 - UDDI Spec Technical Committee Draft, Dated 20041019. Luettu 7.11.2009. Saatavilla: http://www.uddi.org/pubs/uddi_v3.htm
OMG 2009. CORBA Basics. Luettu 7.11.2009. Saatavilla: http://www.omg.org/gettingstarted/corbafaq.htm
RosettaNet 2009. Frequently Asked Question.Luettu 7.11.2009. Saatavilla: http://www.rosettanet.org/AboutRosettaNet/FAQs/tabid/284/Default.aspx
SAP News Desk 2005. Microsoft, IBM, SAP To Discontinue UDDI Web Services Registry Effort. Luettu 7.11.2009. Saatavilla: http://soa.sys-con.com/node/164624
OASIS Open 2006. About ebXML. Luettu 7.11.2009. Saatavilla: http://www.ebxml.org/geninfo.htm
Tekes. RosettaNet luo yhteisiä pelisääntöjä. Luettu 7.11.2009. Saatavilla: http://akseli.tekes.fi/opencms/opencms/OhjelmaPortaali/ohjelmat/SPIN/fi/system/uutinen.html?id=981&nav=Uutisia&arkisto=true
WS-I 2009. Deliverables from the Basic Profile Working Group. Luettu 7.11.2009. Saatavilla: http://www.ws-i.org/deliverables/workinggroup.aspx?wg=basicprofile
Kirjat
Nykänen, Ossi. 2005. XML Vantaa: Docendo Finland Oy
Järvinen, Jani. 2002. Hajautetut verkkopalvelut. Vantaa: Docendo Finland Oy
Kuvat
Kuva 1. http://fi.sun.com/practice/software/soa/images/ig_soa_before.gif
Kuva 2. http://en.wikipedia.org/wiki/File:SOAP.svg
Kuva 3. http://en.wikipedia.org/wiki/File:WSDL_11vs20.png
Kuva 4. (ruutukauppaus)
Kuva 5. http://www.uddi.org/pubs/uddi_v3.htm
Kuva 6. http://www.innoq.com/soa/ws-standards/poster/innoQ WS-Standards Poster 2007-02.pdf
Kuva 7. (ruutukauppaus)
Kuva 8. http://2.bp.blogspot.com/_xDhbUkqcpek/SrqIBuvzEfI/AAAAAAAAAC4/NiKPiaa7eSw/s1600-h/EMML.png
Kuva 9. http://i.zdnet.com/blogs/mashups_with_emml.png
Kuva 10. (ruutukauppaus)
Kuva 11. http://www.neotool.com/pdf/HL7-Evolution-Comparing-V2-to-V3.pdf
Kuva 12. http://www.ringholm.de/images/03030_02.jpg
Kuva 13. http://healthcare.nicewareintl.com/s3/uploaded/1490/graphNWhealthcare-medium.png
Kuva 14. (ruutukauppaus)
Kuva 15. http://java.sun.com/developer/onlineTraining/corba/images/7.gif
Kuva 16. http://www.ibm.com/developerworks/xml/library/x-ebxml/ebXML1.gif