Programavimas

SAAJ: Nėra jokių stygų

Šiuo metu dauguma žiniatinklio paslaugų susideda iš paprasto keitimosi žinutėmis: Klientas susisiekia su interneto tarnyba ir siunčia šiai tarnybai pranešimą. Savo ruožtu žiniatinklio tarnyba apdoroja šią užklausą ir išsiunčia klientui atsakymą. Šis paprastas užklausos / atsakymo modelis modeliuoja tai, kaip HTTP protokolas palengvina kliento / tinklo serverio sąveiką. Kaip ir HTTP atveju, keičiantis žiniatinklio paslaugomis dažnai turi būti dvejetainis turinys, pvz., Vaizdai, dokumentai ar garso įrašai. Šiame straipsnyje pristatoma dvejetainės žiniatinklio paslaugos turinio siuntimas ir gavimas naudojant SOAP (paprastą prieigos prie objekto protokolą) su „Java“ priedų API (SAAJ) 1.2.

Prieš pasineriant į dvejetainių žiniatinklio paslaugų turinio perkėlimo subtilybes, verta atkreipti dėmesį į tai, kad paprasta užklausos / atsakymo stiliaus interneto paslauga prieštarauja paslaugoms, kurios kliento / serverio sąveiką modeliuoja kaip nuotolinių procedūrų skambučius arba RPC. RPC serveris pateikia sąsają, panašią į API. Savo ruožtu klientas pasinaudoja tokia paslauga atlikdamas nuotolinius skambučius į paslaugos API, perduodamas reikalingus parametrus ir gaudamas skambučio sukurtas vertes.

XML pagrindu sukurtas RPC primena būdą, kaip iškviečiate objektus į objektą orientuotoje (OO) sistemoje. Iš tiesų, dirbdami su Java API, skirtu XML pagrįstam RPC (JAX-RPC), jūs retai suprantate, kad dirbate su XML dokumentais, o ne su „Java“ objektais. JAX-RPC leidžia galvoti apie interneto paslaugas kaip apie nuotolinius objektus, panašiai kaip ir su „Java RMI“ (nuotolinio metodo iškvietimas). „JAX-RPC“ vykdymo laikas perkelia aukšto lygio OO metodo iškvietimus į XML dokumentus, kurių tikisi nuotolinė žiniatinklio tarnyba. Nors RPC stiliaus interneto paslaugos dažnai teikia patogesnį programavimo modelį, RPC skambučiai taip pat turi pasikliauti žemesnio lygio pranešimų sluoksniu keisdamiesi XML pranešimais, sudarančiais nuotolinį skambutį.

Kai kurioms interneto paslaugoms dažnai naudinga tiesiogiai programuoti į tą žemesnio lygio pranešimų sluoksnį. Pavyzdžiui, jei norite pasinaudoti interneto paslauga, kuri sunaudoja pirkimo užsakymo dokumentą ir grąžina kvitą, galite lengvai modeliuoti tą dokumentų mainą kaip vieną užklausos / atsakymo pranešimų mainą. Užuot iškėlę nuotolinį metodą, sukursite XML pranešimus, siųsite juos tiesiogiai žiniatinklio tarnybai ir apdorosite paslaugos XML atsakymą, jei toks yra. Kadangi SOAP apibrėžia bendrą žiniatinklio tarnybos pranešimų formatą, turėsite sukonstruoti SOAP reikalavimus atitinkančius pranešimus ir, kai paslauga atsakys, tuos SOAP atsakymo pranešimus išanalizuokite atgal į jūsų suprantamą formatą.

SAAJ yra patogi biblioteka, skirta kurti ir skaityti SOAP pranešimus, taip pat leidžia jums siųsti ir gauti SOAP pranešimus per tinklą. SAAJ apibrėžia vardų sritį javax.xml.soap. Tame pakete esančios klasės iš pradžių buvo „Java API for XML Messaging“ (JAXM) dalis, tačiau neseniai buvo atskirtos į savo API. JAXM remiasi SAAJ formuodamas ir tvarkydamas SOAP pranešimus ir prideda pranešimų patikimumą bei kitas XML pranešimams būdingas funkcijas. SAAJ yra būtinas J2EE („Java 2 Platform“, „Enterprise Edition“) 1.4 komponentas, o JAXM - ne. Šiame straipsnyje pagrindinis dėmesys skiriamas vienam iš naudingiausių SAAJ aspektų: galimybei pridėti dvejetainį turinį prie SOAP pranešimo.

Priedų nauda

Nors SOAP dizaino centras sutelkia dėmesį į XML dokumentų įklijavimą į pranešimą, SOAP priedų funkcija išplečia SOAP pranešimą, įtraukdama be įprastos SOAP dalies ir nulį ar daugiau priedų, kaip parodyta 1 paveiksle. Kiekvieną priedą apibrėžia MIME tipas ir jis gali prisiimti bet kokį turinį, vaizduojamą kaip baitų srautą.

SOAP priedų funkcija yra naudingiausia, kai klientas nori perduoti dvejetainius duomenis, tokius kaip vaizdo ar garso duomenys, į interneto paslaugą. Be SOAP priedų, siųsti dvejetainius duomenis būtų sunkiau. Pavyzdžiui, kliento SOAP pranešimas gali perduoti dvejetainio failo URL adresą. Tada klientas turėtų valdyti HTTP serverį, kad žiniatinklio tarnyba leistų nuskaityti tą failą. Tai būtų nepagrįsta našta bet kuriam interneto paslaugų klientui, ypač klientams, naudojantiems ribotų išteklių įrenginius, pvz., Skaitmeninius fotoaparatus ar skaitytuvus. SOAP priedų galimybė leidžia bet kuriam žiniatinklio paslaugų klientui, galinčiam perduoti SOAP pranešimus, įdėti dvejetainius failus tiesiai į SOAP pranešimą.

Pavyzdžiui, SOAP priedai yra naudingi bendraujant su portalo svetainėmis. Apsvarstykite nekilnojamojo turto agentūrų tinklą, kuriam reikia išplatinti parduodamų namų aprašymus ir nuotraukas į centralizuotą nekilnojamojo turto paieškos portalą. Jei portale veikia servletas, leidžiantis skelbti SOAP pranešimus su priedais, nekilnojamojo turto agentūra galėtų atnaujinti savo sąrašus keliais SOAP pranešimais, įskaitant tų namų nuotraukas. SOAP pranešimo turinys gali įterpti ypatybės aprašą, o SOAP priedai gali turėti vaizdo failus. Pagal šį scenarijų, kai portalo operatoriaus servletas gauna tokį pranešimą, jis grąžina patvirtinimo dokumentą, kuriame nurodoma, ar įrašas yra portale. 2 paveiksle pavaizduota tokia interneto paslauga.

SOAP su priedais pranešimo anatomija

SOAP žinučių su priedais W3C („World Wide Web Consortium“) pastaba (žr. Išteklius) neprideda naujų funkcijų prie SOAP. Atvirkščiai, jis apibrėžia, kaip pasinaudoti MIME tipais SOAP pranešime, norint apibrėžti priedus, ir kaip nurodyti tuos priedus iš SOAP turinio.

MIME tipas daugiadalis / susijęs apibrėžia dokumentus, susidedančius iš kelių susijusių dalių. SOAP pranešimai su priedais turi atitikti daugiadalis / susijęs MIME tipas. Žemiau pateiktame pavyzdyje parodyta a daugiadalis / susijęs SOAP pranešimas, susietas su HTTP protokolu, su dviem priedais:

POST / propertyListing HTTP / 1.1 Host: www.realproperties.com Turinio tipas: Daugiasalis / Susijęs; riba = MIME_ riba; type = text / xml; Turinio ilgis: NNNN - MIME_boundary Turinio tipas: text / xml; charset = UTF-8 Turinio perkėlimo kodavimas: 8 bitų „Content ID“: „Really Nice Homes, Inc.“. Pridėti 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-- 

Pirmiau pateiktą daugiadalį pranešimą sudaro daugybė MIME antraščių ir susijusių duomenų. Dokumento pagrindas yra SOAP turinys. Kadangi SOAP korpuse yra tik XML duomenys, viso pranešimo MIME tipas yra tekstas / xml. Po SOAP voko yra du priedai, kiekvienas iš jų atitinka vaizdo failą, išsiųstą kartu su pranešimu.

Turinio ID identifikuoja kiekvieną priedą. „W3C Note“ leidžia turinio ID arba turinio vietai nurodyti priedus, tačiau pirmenybę teikia pirmiesiems. Tokie turinio ID veikia kaip Uniform Resource Identifier (URI) nuorodos į priedus; SOAP 1.1 kodavimo taisyklės apibrėžia, kaip SOAP pranešime nurodyti šaltinį naudojant URI, kuris gali nurodyti bet kokį turinį, ne tik XML (žr. „SOAP 1.1“ 5 skyrių „Resursai“). SOAP procesorius išsprendžia šias URI nuorodas, kai apdoroja pranešimą. Remiantis aukščiau pateiktu pavyzdžiu, SOAP procesorius susieja elementą priekisVaizdas su duomenų skiltimi su „Content ID“ nuosavybė[email protected] SOAP pranešime.

Sukurkite ir išsiųskite SOAP pranešimą su priedais

SAAJ leidžia jums sukurti ir redaguoti bet kurią SOAP pranešimo dalį, įskaitant priedus. Didžioji dalis SAAJ remiasi abstrakčiomis klasėmis ir sąsajomis, kad kiekvienas paslaugų teikėjas galėtų įgyvendinti SAAJ savo produktuose. „Sun Microsystems“ informacinis diegimas pateikiamas kartu su „Java Web Services Developer Pack“ (JWSDP).

Kadangi SOAP pranešimai yra tik speciali XML dokumentų forma, JAAS remiasi „Document Object Model“ (DOM) API, skirta XML apdorojimui. Dauguma SOAP pranešimų komponentų kyla iš javax.xml.soap.Node sąsaja, kuri savo ruožtu yra a org.w3c.dom.Node poklasis. SAAJ poklasiai Mazgas pridėti SOAP būdingų konstrukcijų. Pavyzdžiui, specialusis Mazgas, MUILASElementas, reiškia SOAP pranešimo elementą.

Tiesioginis SAAJ priklausomybės nuo sąsajų ir abstrakčių klasių rezultatas yra tai, kad dauguma su SOAP susijusių užduočių atliekate gamykliniais metodais. Norėdami susieti savo programą su SAAJ API, pirmiausia sukurkite „SOAPConnection“SOAPConnectionFactory. Norėdami kurti ir redaguoti SOAP pranešimus, taip pat galite inicializuoti „MessageFactory“ ir a SOAPFactory. „MessageFactory“ leidžia kurti SOAP pranešimus ir SOAPFactory pateikia atskirų SOAP pranešimo dalių kūrimo metodus:

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

Turėdami šiuos įrankius, galite sukurti SOAP pranešimą, kurį nekilnojamojo turto agentūros klientas naudos išsiųsdamas įrašo atnaujinimą į portalo svetainę.

SAAJ siūlo keletą būdų sukurti naują SOAP pranešimą. Šis pavyzdys rodo paprasčiausią būdą, kuris sukuria tuščią SOAP pranešimą su voku, antraštę ir tekstą tame voke. Kadangi šiame pranešime jums nereikia SOAP antraštės, galite pašalinti tą elementą iš pranešimo:

SOAPMessage pranešimas = gamykla.createMessage (); SOAPHeader antraštė = message.getSOAPHeader (); header.detachNode (); 

XML struktūros įtraukimas į pranešimo turinį yra paprastas:

SOAPBody body = message.getSOAPBody (); Vardų sąrašasElementName = soapFactory.createName ("propertyListing", "realProperty", "//schemas.realhouses.com/listingSubmission"); SOAPBodyElement listingElement = body.addBodyElement (listingElementName); Vardas vardas = muilasFactory.createName ("id"); listElement.addAttribute (atributas, "nuosavybės_1234"); SOAPElement listingAgency = listingElement.addChildElement ("listingAgency"); listingAgency.addTextNode („Really Nice Homes, Inc“); SOAPElement listingType = listingElement.addChildElement ("listingType"); listType.addTextNode ("pridėti"); SOAPElement propertyAddress = listingElement.addChildElement ("propertyAddress"); SOAPElement gatvė = propertyAddress.addChildElement ("gatvė"); street.addTextNode ("1234 Main St"); SOAPElement miestas = propertyAddress.addChildElement ("miestas"); city.addTextNode („Pleasantville“); SOAPElement valstybė = nuosavybės adresas.addChildElement ("būsena"); state.addTextNode („CA“); SOAPElement zip = propertyAddress.addChildElement ("zip"); zip.addTextNode ("94521"); SOAPElement listPrice = listingElement.addChildElement ("listPrice"); listPrice.addTextNode ("25000"); 

Atminkite, kad prie atributo pridedate unikalų nuosavybės ID propertyListing elementas. Toliau jūs kvalifikuojate propertyListing elementas su a QNamearba vardų pavadinimą žinantis vardas.

Priedus prie SOAP pranešimo galite pridėti keliais būdais. Šiame pavyzdyje pirmiausia sukuriate elementus, kurie žymi išvardyto turto priekinius ir interjero vaizdus. Kiekvienas turi href atributas, nurodantis priedo turinio ID:

String frontImageID = "nuosavybė[email protected]"; SOAPElement frontImRef = listingElement.addChildElement ("frontImage"); Vardas hrefAttName = muilasFactory.createName ("href"); frontImRef.addAttribute (hrefAttName, frontImageID); Eilutė interiorID = "[email protected]"; SOAPElement interiorImRef = listingElement.addChildElement ("interiorImage"); interiorImRef.addAttribute (hrefAttName, interiorID); 

Norėdami lengvai pridėti reikalingus vaizdo failus prie pranešimo, naudokite a javax.activation.DataHandler objektas iš „JavaBeans“ aktyvinimo sistemos. „DataHandler“ gali automatiškai aptikti jam perduotą duomenų tipą, todėl priedui gali automatiškai priskirti atitinkamą MIME turinio tipą:

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

Arba galite pereiti Objektas, kartu su teisingu MIME tipu, į createAttachmentPart (). Šis metodas primena pirmąjį. Vidaus SAAJ įgyvendinimas greičiausiai ieškos „DataContentHandler“ tvarkyti nurodytą MIME tipą. Jei nepavyksta rasti tinkamo prižiūrėtojo, createAttachmentPart () išmes an Neteisėtas argumentas. Išimtis:

URL url2 = naujas URL ("file: ///export/files/pic2.jpg"); Vaizdas im = Toolkit.getDefaultToolkit (). CreateImage (url2); AttachmentPart att2 = message.createAttachmentPart (im, "image / jpeg"); att2.setContentId (interiorID); message.addAttachmentPart (att2); 
$config[zx-auto] not found$config[zx-overlay] not found