Ohjelmointi

SAAJ: Ei merkkijonoja

Tämän kirjoituksen aikaan suurin osa verkkopalveluista koostuu yksinkertaisista sanomanvaihdoista: Asiakas ottaa yhteyttä verkkopalveluun ja lähettää viestin kyseiselle palvelulle. Verkkopalvelu puolestaan ​​käsittelee pyynnön ja lähettää sitten vastauksen asiakkaalle. Tämä yksinkertainen pyyntö- / vastausmalli mallintaa tapaa, jolla HTTP-protokolla helpottaa asiakkaan / verkkopalvelimen vuorovaikutusta. Kuten HTTP: n kohdalla, verkkopalveluviestien vaihdon on usein sisällettävä binaarisisältöä, kuten kuvia, asiakirjoja tai äänileikkeitä. Tässä artikkelissa esitellään binaarisen verkkopalvelusisällön lähettäminen ja vastaanottaminen SOAP: n (Simple Object Access Protocol) ja liitteiden API for Java (SAAJ) 1.2: n avulla.

Ennen kuin sukeltaa binaarisen verkkopalvelusisällön siirtämisen monimutkaisuuteen, kannattaa huomauttaa, että yksinkertainen pyyntö- / vastaustyylinen verkkopalvelu on ristiriidassa palveluiden kanssa, jotka muokkaavat asiakkaan / palvelimen vuorovaikutusta etäprotokollakutsuna tai RPC: nä. RPC: ssä palvelin paljastaa käyttöliittymän, joka muistuttaa API: ta. Puolestaan ​​asiakas vetoaa tällaiseen palveluun soittamalla etäkutsuja palvelun sovellusliittymälle, välittämällä vaaditut parametrit ja vastaanottamalla puhelun tuottamat arvot.

XML-pohjainen RPC muistuttaa tapaa, jolla kutsut objektit olio-järjestelmässä (OO). Työskennellessäsi Java-sovellusliittymän XML-pohjaisen RPC: n (JAX-RPC) kanssa, huomaat harvoin, että työskentelet XML-asiakirjojen, ei Java-objektien kanssa. JAX-RPC antaa sinun ajatella verkkopalveluja etäobjekteina, aivan kuten tekisit Java RMI: n (Remote Method Invocation) kanssa. JAX-RPC-ajonaikainen käännös muuntaa korkean tason OO-menetelmäkutsut Web-etäpalvelun odottamille XML-asiakirjoille. Vaikka RPC-tyyliset verkkopalvelut tarjoavat usein helpomman ohjelmointimallin, RPC-puheluiden on myös luotettava alemman tason viestintäkerrokseen vaihtaakseen etäpuhelun muodostavat XML-viestit.

Joillekin verkkopalveluille on usein hyödyllistä ohjelmoida suoraan kyseiselle alemman tason viestintäkerrokselle. Esimerkiksi, jos haluat vedota verkkopalveluun, joka kuluttaa ostotilausasiakirjan ja palauttaa kuitin, voit helposti mallintaa kyseisen asiakirjanvaihdon yhtenä pyyntö- / vastausviestinvaihtona. Etämenetelmäkutsujen tekemisen sijaan rakennat XML-sanomat, lähetät nämä viestit suoraan verkkopalveluun ja käsittelet palvelun XML-vastauksen, jos sellaista on. Koska SOAP määrittelee verkkopalveluviestien yleisen sanomamuodon, sinun on rakennettava SOAP-yhteensopivia viestejä ja jäsenneltävä nämä SOAP-vastausviestit takaisin palvelun muotoon, jonka ohjelma ymmärtää.

SAAJ tarjoaa kätevän kirjaston SOAP-viestien luomiseen ja lukemiseen, ja voit myös lähettää ja vastaanottaa SOAP-viestejä verkon kautta. SAAJ määrittelee nimitilan javax.xml.soap. Kyseisessä paketissa olevat luokat muodostivat alun perin osan Java API for XML Messaging (JAXM) -ohjelmasta, mutta ne erotettiin äskettäin omaksi API: kseen. JAXM luottaa SAAJ: iin SOAP-sanomien rakentamisessa ja manipuloinnissa, ja lisää viestien luotettavuuden ja muita XML-viestintään liittyviä ominaisuuksia. Vaikka SAAJ on pakollinen komponentti J2EE (Java 2 Platform, Enterprise Edition) 1.4: ssa, JAXM ei ole. Tämä artikkeli keskittyy yhteen SAAJ: n hyödyllisimmistä näkökohdista: kyvystä liittää binaarisisältö SOAP-viestiin.

Liitteiden edut

Vaikka SOAPin suunnittelukeskus keskittyy XML-asiakirjojen kapseloimiseen viestiin, SOAP: n liitetiedosto laajentaa SOAP-sanomaa tavallisen SOAP-osan lisäksi nollaan tai useampaan liitteeseen, kuten kuvasta 1 näkyy. Jokainen liitetiedosto on määritelty MIME-tyypillä, ja se voi ottaa kaiken sisällön, joka on esitetty tavuvirrana.

SOAP: n kiinnitysominaisuus osoittautuu hyödyllisimmäksi, kun asiakas haluaa lähettää binaaritietoja, kuten kuva- tai äänidataa, verkkopalveluun. Ilman SOAP-liitetiedostoja binääridatan lähettäminen osoittautuisi vaikeammaksi. Esimerkiksi asiakkaan SOAP-viesti voisi välittää binaaritiedoston URL-osoitteen. Asiakkaan on sitten käytettävä HTTP-palvelinta, jotta verkkopalvelu voi noutaa kyseisen tiedoston. Se merkitsisi kohtuutonta taakkaa kaikille verkkopalveluasiakkaille, etenkin asiakkaille, jotka käyttävät rajoitettujen resurssien laitteita, kuten digitaalikameroita tai skannereita. SOAP: n liitäntäominaisuuden avulla kaikki verkkopalveluasiakkaat, jotka pystyvät lähettämään SOAP-viestejä, upottavat binaaritiedostot suoraan SOAP-sanomaan.

Esimerkiksi SOAP-liitteet osoittautuvat käteviksi vuorovaikutuksessa portaalin verkkosivustojen kanssa. Harkitse kiinteistövälitystoimisto-verkostoa, jonka on jaettava kuvauksia ja valokuvia myytävistä kodeista keskitetylle kiinteistöhakuportaalille. Jos portaalissa on servlet, joka sallii liitteenä olevien SOAP-viestien lähettämisen, kiinteistövälitystoimisto voisi päivittää luetteloaan muutamalla SOAP-viestillä, mukaan lukien valokuvat näistä kodeista. SOAP-sanoman runko saattaa upottaa ominaisuuden kuvauksen ja SOAP-liitteet voivat kuljettaa kuvatiedostoja. Tuossa skenaariossa, kun portaalinoperaattorin servlet saa tällaisen viestin, se palauttaa kuittausasiakirjan, jossa ilmoitetaan viestin saatavuus portaalissa. Kuva 2 kuvaa tällaista verkkopalvelua.

SOAP: n anatomia liitetiedostoilla

SOAP-viestit liitteillä W3C (World Wide Web Consortium) -huomautus (katso Resurssit) ei lisää uusia ominaisuuksia SOAP: iin. Pikemminkin siinä määritetään, kuinka MIME-tyyppejä voidaan hyödyntää SOAP-sanomassa määritettäessä liitteitä, ja kuinka viitata näihin liitteisiin SOAP-rungossa.

MIME-tyyppi moniosainen / liittyvä määrittelee asiakirjat, jotka koostuvat useista toisiinsa liittyvistä osista. Liitteiden sisältävien SOAP-viestien on noudatettava moniosainen / liittyvä MIME-tyyppi. Alla olevassa esimerkissä näkyy a moniosainen / liittyvä SOAP-viesti, sidottu HTTP-protokollaan, kahdella liitteellä:

POST / propertyListing HTTP / 1.1 Host: www.realproperties.com Sisältötyyppi: Moniosainen / Liittyvä; raja = MIME_raja; type = teksti / xml; Sisällön pituus: NNNN - MIME_raja Sisältötyyppi: teksti / xml; charset = UTF-8 Sisällönsiirto-koodaus: 8-bittinen Content-ID: Really Nice Homes, Inc. Lisää 1234 Main St Pleasantville CA 94323 250000 --MIME_boundary Content-type: image / jpeg Content-ID: ... JPEG DATA ..... --MIME_boundary Content-Type: image / jpeg Content-ID: .... JPEG DATA ..... --MIME_boundary-- 

Yllä oleva moniosainen viesti käsittää sarjan MIME-otsikoita ja niihin liittyviä tietoja. Asiakirjan juuressa on SOAP-runko. Koska SOAP-runko sisältää vain XML-tietoja, koko viestin MIME-tyyppi on teksti / xml. SOAP-kirjekuoren jälkeen on kaksi liitettä, joista kukin vastaa sanoman mukana lähetettyä kuvatiedostoa.

Sisältötunnus tunnistaa jokaisen liitteen. W3C-muistiinpanon avulla joko sisältötunnus tai sisällön sijainti viittaa liitteisiin, mutta se antaa etusijan edellisille. Tällaiset sisältötunnukset toimivat URI-viitteinä liitteisiin; SOAP 1.1 -koodaussäännöt määrittelevät, miten viitata resurssiin SOAP-sanomassa URI: n kautta, joka voi viitata mihin tahansa sisältöön, ei vain XML: ään (katso Resurssien SOAP 1.1: n osa 5). SOAP-prosessori ratkaisee nämä URI-viitteet prosessoidessaan viestiä. Yllä olevan esimerkin perusteella SOAP-prosessori liittää elementin edessä Content ID -tietoyksikön kanssa [email protected] SOAP-viestissä.

Luo ja lähetä SOAP-viesti liitteineen

SAAJ: n avulla voit luoda ja muokata mitä tahansa SOAP-viestin osaa, mukaan lukien liitteet. Suurin osa SAAJ: sta perustuu abstrakteihin luokkiin ja rajapintoihin, jotta jokainen palveluntarjoaja voi toteuttaa SAAJ: n omissa tuotteissaan. Sun Microsystemsin viitetoteutus tulee Java Web Services Developer Packin (JWSDP) mukana.

Koska SOAP-sanomat edustavat vain erityistä XML-asiakirjojen muotoa, JAAS perustuu XML-käsittelyä varten Dokumenttiobjektimalli (DOM) -sovellusliittymään. Suurin osa SOAP-viestikomponenteista laskeutuu javax.xml.soap.Node käyttöliittymä, joka puolestaan ​​on a org.w3c.dom.Node alaluokka. SAAJ-alaluokat Solmu lisätä SOAP-spesifisiä rakenteita. Esimerkiksi erityinen Solmu, Saippua, edustaa SOAP-viestielementtiä.

Suora tulos SAAJ: n riippuvuudesta rajapinnoista ja abstrakteista luokista on se, että suoritat suurimman osan SOAP: iin liittyvistä tehtävistä tehdasmenetelmillä. Yhdistä sovelluksesi SAAJ-sovellusliittymään luomalla ensin SOAP-yhteys alkaen a SOAPConnectionFactory. Voit myös luoda ja muokata SOAP-viestejä a MessageFactory ja a Saippuatehdas. MessageFactory voit luoda SOAP-viestejä ja Saippuatehdas tarjoaa menetelmät SOAP-viestin yksittäisten osien luomiseksi:

SOAPConnectionFactory spConFactory = SOAPConnectionFactory.newInstance (); SOAPConnection con = spConFactory.createConnection (); SOAPFactory soapFactory = SOAPFactory.newInstance (); 

Kun nämä työkalut ovat paikallaan, voit luoda SOAP-viestin, jonka kiinteistötoimiston asiakas lähettää luettelopäivityksen portaalin verkkosivustolle.

SAAJ tarjoaa useita tapoja luoda uusi SOAP-viesti. Seuraava esimerkki näyttää yksinkertaisen menetelmän, jolla luodaan tyhjä SOAP-viesti, jossa on kirjekuori, otsikko ja runko tässä kirjekuoressa. Koska et tarvitse SOAP-otsikkoa tässä viestissä, voit poistaa kyseisen elementin viestistä:

SOAPMessage-viesti = tehdas.createMessage (); SOAPHeader header = viesti.getSOAPHeader (); header.detachNode (); 

XML-rakenteen lisääminen viestirunkoon osoittautuu suoraviivaiseksi:

SOAPBody body = viesti.getSOAPBody (); Nimi listingElementName = soapFactory.createName ("propertyListing", "realProperty", "//schemas.realhouses.com/listingSubmission"); SOAPBodyElement listElement = body.addBodyElement (listElementName); Nimi attname = saippuaFactory.createName ("id"); listElement.addAttribute (attname, "omaisuuden_1234"); SOAPElement listAgency = listingElement.addChildElement ("listingAgency"); listingAgency.addTextNode ("Really Nice Homes, Inc"); SOAPElement listType = listingElement.addChildElement ("listatyyppi"); listType.addTextNode ("lisää"); SOAPElement propertyAddress = listingElement.addChildElement ("omaisuuden osoite"); SOAPElement-katu = omaisuusosoite.addChildElement ("katu"); street.addTextNode ("1234 Main St"); SOAPElement kaupunki = omaisuusosoite.addChildElement ("kaupunki"); city.addTextNode ("Pleasantville"); SOAPElement-tila = ominaisuusosoite.addChildElement ("tila"); state.addTextNode ("CA"); SOAPElement zip = omaisuudenosoite.addChildElement ("zip"); zip.addTextNode ("94521"); SOAPElement listPrice = listElement.addChildElement ("listPrice"); listPrice.addTextNode ("25000"); 

Huomaa, että lisäät ominaisuuden yksilöllisen tunnuksen attribuuttina propertyListing elementti. Lisäksi hyväksyt propertyListing elementti a: lla QName, tai nimiavaruustietoinen nimi.

Voit lisätä liitteitä SOAP-viestiin useilla tavoilla. Tässä esimerkissä luot ensin elementit, jotka merkitsevät luetellun kiinteistön etu- ja sisäkuvia. Jokaisella on href attribuutti, joka osoittaa liitteen sisältötunnuksen:

Merkkijono frontImageID = "[email protected]"; SOAPElement frontImRef = listingElement.addChildElement ("frontImage"); Nimi hrefAttName = soapFactory.createName ("href"); frontImRef.addAttribute (hrefAttName, frontImageID); Merkkijono interiorID = "[email protected]"; SOAPElement interiorImRef = listElement.addChildElement ("interiorImage"); interiorImRef.addAttribute (hrefAttName, interiorID); 

Liitä tarvittavat kuvatiedostot helposti viestiin käyttämällä a javax.activation.DataHandler objekti JavaBeansin aktivointikehyksestä. DataHandler pystyy tunnistamaan automaattisesti sille välitetyn tietotyypin ja voi siten määrittää liitteelle automaattisesti sopivan MIME-sisältötyypin:

URL url = uusi URL ("tiedosto: ///export/files/pic1.jpg"); DataHandler dataHandler = uusi DataHandler (URL); AttachmentPart att = message.createAttachmentPart (dataHandler); att.setContentId (frontImageID); message.addAttachmentPart (att); 

Vaihtoehtoisesti voit ehkä ohittaa Esineja oikea MIME-tyyppi createAttachmentPart (). Tuo menetelmä muistuttaa ensimmäistä. Sisäisesti SAAJ: n toteutus todennäköisesti etsii DataContentHandler käsitellä määritettyä MIME-tyyppiä. Jos se ei löydä sopivaa ohjaajaa, createAttachmentPart () heittää IllegalArgumentException:

URL url2 = uusi URL ("tiedosto: ///export/files/pic2.jpg"); Kuva im = Toolkit.getDefaultToolkit (). CreateImage (url2); AttachmentPart att2 = message.createAttachmentPart (im, "kuva / jpeg"); att2.setContentId (interiorID); message.addAttachmentPart (att2);