Programmering

SAAJ: Ingen strenger festet

I skrivende stund består de fleste webtjenester av enkel meldingsutveksling: En klient kontakter en webtjeneste og sender en melding til den tjenesten. Nettjenesten behandler i sin tur forespørselen og sender deretter svaret tilbake til klienten. Det enkle forespørsels- / svarmønsteret modellerer måten HTTP-protokollen letter klient / webserverinteraksjoner. Som med HTTP, må utveksling av webtjenestemeldinger ofte inneholde binært innhold, for eksempel bilder, dokumenter eller lydklipp. Denne artikkelen introduserer sending og mottak av binært webtjenesteinnhold ved hjelp av SOAP (Simple Object Access Protocol) med Attachments API for Java (SAAJ) 1.2.

Før du dykker inn i komplikasjonene ved å overføre binært webtjenesteinnhold, er det verdt å påpeke at en enkel forespørsel / respons-stil webtjeneste står i kontrast til tjenester som motiverer klient / serverinteraksjon som eksterne prosedyreanrop, eller RPCer. I en RPC avslører en server et grensesnitt som ligner et API. I sin tur påkaller en klient en slik tjeneste ved å foreta eksterne samtaler på tjenestens API, sende de nødvendige parametrene og motta verdiene samtalen produserer.

XML-basert RPC ligner måten du påkaller objekter i et objektorientert (OO) system. Når du arbeider med Java API for XML-basert RPC (JAX-RPC), blir du sjelden klar over at du jobber med XML-dokumenter, ikke Java-objekter. JAX-RPC lar deg tenke på webtjenester som eksterne objekter, akkurat som du ville gjort med Java RMI (Remote Method Invocation). JAX-RPC-kjøretiden oversetter OO-metoden på høyt nivå til XML-dokumentene som forventes av den eksterne nettjenesten. Mens RPC-stil Web-tjenester ofte gir en mer praktisk programmeringsmodell, må RPC-samtaler også stole på et meldingslag på lavere nivå for å utveksle XML-meldingene som utgjør det eksterne anropet.

For noen webtjenester er det ofte nyttig å programmere direkte til det meldingslaget på lavere nivå. For eksempel, hvis du ønsker å påkalle en webtjeneste som bruker et bestillingsdokument og returnerer en kvittering, kan du enkelt modellere dokumentutvekslingen som en enkelt forespørsel / svarmeldingsutveksling. I stedet for å foreta eksterne metodeinnkallinger, vil du konstruere XML-meldinger, sende disse meldingene direkte til en webtjeneste og behandle tjenestens XML-respons, hvis noen eksisterer. Siden SOAP definerer det vanlige meldingsformatet for webtjenestemeldinger, må du konstruere SOAP-samsvarende meldinger, og når tjenesten svarer, analyserer du disse SOAP-svarmeldingene i et format programmet forstår.

SAAJ tilbyr et praktisk bibliotek for å konstruere og lese SOAP-meldinger, og lar deg også sende og motta SOAP-meldinger over hele nettverket. SAAJ definerer navneområdet javax.xml.såpe. Klassene som ligger i den pakken utgjorde opprinnelig en del av Java API for XML Messaging (JAXM), men ble nylig skilt inn i sin egen API. JAXM er avhengig av SAAJ for konstruksjon og manipulering av SOAP-meldinger, og legger til meldingspålitelighet og andre funksjoner som er spesifikke for XML-meldinger. Mens SAAJ er en nødvendig komponent i J2EE (Java 2 Platform, Enterprise Edition) 1.4, er ikke JAXM det. Denne artikkelen fokuserer på en av SAAJs mest nyttige aspekter: muligheten til å legge ved binært innhold til en SOAP-melding.

Fordelene med vedlegg

Mens SOAPs designsenter fokuserer på å kapsle inn XML-dokumenter i en melding, utvider SOAPs vedleggsfunksjon en SOAP-melding til å inkludere, i tillegg til den vanlige SOAP-delen, null eller flere vedlegg, som figur 1 viser. Hvert vedlegg er definert av en MIME-type og kan anta alt innhold som er representert som en byte-strøm.

SOAPs vedleggsfunksjon viser seg som mest nyttig når en klient ønsker å overføre binære data, for eksempel et bilde eller lyddata, til en webtjeneste. Uten SOAP-vedlegg ville det være vanskeligere å sende et stykke binære data. For eksempel kan en klients SOAP-melding formidle den binære filens URL-adresse. Klienten må da operere en HTTP-server for å la webtjenesten hente filen. Dette vil utgjøre en unødig belastning for enhver webtjenesteklient, spesielt for klienter som kjører på enheter med begrenset ressurs, for eksempel digitale kameraer eller skannere. SOAPs vedleggsmulighet lar enhver webtjenesteklient i stand til å overføre SOAP-meldinger legge inn binære filer direkte i en SOAP-melding.

SOAP-vedlegg, for eksempel, er nyttige når de kommuniserer med portalnettsteder. Vurder et eiendomsmeglernettverk som trenger å distribuere beskrivelser og fotografier av boliger som er til salgs til en sentralisert portal for eiendomssøk. Hvis portalen driver en servlet som gjør det mulig å legge ut SOAP-meldinger med vedlegg, kan et eiendomsmegler oppdatere oppføringene sine med noen få SOAP-meldinger, inkludert bilder av hjemmene. SOAP-meldingsdelen kan legge inn beskrivelse av eiendommen, og SOAP-vedlegg kan bære bildefilene. Under det scenariet, når en portaloperatørs servlet mottar en slik melding, vil den returnere et bekreftelsesdokument som indikerer innleggets tilgjengelighet på portalen. Figur 2 illustrerer en slik webtjeneste.

Anatomien til SOAP med vedleggsmelding

SOAP-meldinger med vedlegg W3C (World Wide Web Consortium) Merk (se Ressurser) legger ikke til nye funksjoner i SOAP. Snarere definerer det hvordan du kan dra nytte av MIME-typer i en SOAP-melding for å definere vedlegg, og hvordan du skal referere til disse vedleggene fra SOAP-kroppen.

MIME-typen flerdelt / relatert definerer dokumenter som består av flere relaterte deler. SOAP-meldinger med vedlegg må følge flerdelt / relatert MIME-type. Eksemplet nedenfor viser a flerdelt / relatert SOAP-melding, bundet til HTTP-protokollen, med to vedlegg:

POST / propertyListing HTTP / 1.1 Host: www.realproperties.com Content-Type: Multipart / Related; grense = MIME_grense; type = tekst / xml; Innholdslengde: NNNN --MIME_boundary Innholdstype: tekst / xml; charset = UTF-8 Content-Transfer-Encoding: 8bit Content-ID: Really Nice Homes, Inc. Legg til 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-- 

Ovennevnte flerdelt melding består av en serie MIME-headere og relaterte data. Roten til dokumentet er SOAP-kroppen. Fordi SOAP-kroppen bare inneholder XML-data, er MIME-typen for hele meldingen tekst / xml. Etter SOAP-konvolutten følger to vedlegg, som hver tilsvarer en bildefil sendt sammen med meldingen.

En innholds-ID identifiserer hvert vedlegg. W3C-notatet lar enten en innholds-ID eller et innholdssted referere til vedleggene, men den foretrekker førstnevnte. Slike innholds-ID-er fungerer som URI-referanser (Uniform Resource Identifier) ​​til vedlegg; kodingsreglene for SOAP 1.1 definerer hvordan man skal referere til en ressurs i en SOAP-melding via en URI som kan referere til noe innhold, ikke bare XML (se avsnitt 5 i SOAP 1.1 i Ressurser). En SOAP-prosessor løser disse URI-referansene når den behandler meldingen. Basert på eksemplet ovenfor, tilknytter SOAP-prosessoren elementet frontImage med dataseksjonen med Content ID [email protected] i SOAP-meldingen.

Opprett og send en SOAP-melding med vedlegg

SAAJ lar deg opprette og redigere en hvilken som helst del av en SOAP-melding, inkludert vedlegg. Det meste av SAAJ er basert på abstrakte klasser og grensesnitt slik at hver leverandør kan implementere SAAJ i sine egne produkter. Sun Microsystems 'referanseimplementering kommer med Java Web Services Developer Pack (JWSDP).

Siden SOAP-meldinger bare representerer en spesiell form for XML-dokumenter, bygger JAAS på Document Object Model (DOM) API for XML-behandling. De fleste SOAP-meldingskomponenter stammer fra javax.xml.soap.Node grensesnitt, som igjen er et org.w3c.dom.Node underklasse. SAAJ-underklasser Node for å legge til SOAP-spesifikke konstruksjoner. For eksempel en spesiell Node, SOAPElement, representerer et SOAP-meldingselement.

Et direkte resultat av SAAJs avhengighet av grensesnitt og abstrakte klasser er at du utfører de fleste SOAP-relaterte oppgaver via fabrikkmetoder. For å koble søknaden din til SAAJ API, oppretter du først en SOAPConnection fra en SOAPConnectionFactory. For å opprette og redigere SOAP-meldinger kan du også initialisere a MessageFactory og en SOAPFactory. MessageFactory lar deg lage SOAP-meldinger, og SOAPFactory gir metodene for å lage individuelle deler av en SOAP-melding:

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

Med disse verktøyene på plass, kan du opprette en SOAP-melding en klient fra et eiendomsmegler vil bruke til å sende en listeoppdatering til et portalnettsted.

SAAJ tilbyr flere måter å lage en ny SOAP-melding på. Følgende eksempel viser den enkleste metoden som oppretter en tom SOAP-melding med en konvolutt, og overskrift og brødtekst i konvolutten. Siden du ikke trenger en SOAP-overskrift i denne meldingen, kan du fjerne elementet fra meldingen:

SOAPMessage melding = fabrikk.createMessage (); SOAPHeader header = message.getSOAPHeader (); header.detachNode (); 

Å legge til XML-strukturen i meldingsteksten viser seg å være grei:

SOAPBody body = message.getSOAPBody (); NavnelisteElementName = soapFactory.createName ("propertyListing", "realProperty", "//schemas.realhouses.com/listingSubmission"); SOAPBodyElement listingElement = body.addBodyElement (listingElementName); Navn attname = soapFactory.createName ("id"); listingElement.addAttribute (attname, "property_1234"); SOAPElement listingAgency = listingElement.addChildElement ("listingAgency"); listingAgency.addTextNode ("Virkelig hyggelige hjem, Inc"); SOAPElement listingType = listingElement.addChildElement ("listingType"); listingType.addTextNode ("add"); SOAPElement propertyAddress = listingElement.addChildElement ("propertyAddress"); SOAPElement street = propertyAddress.addChildElement ("gate"); street.addTextNode ("1234 Main St"); SOAPElement city = propertyAddress.addChildElement ("by"); city.addTextNode ("Pleasantville"); SOAPElement state = propertyAddress.addChildElement ("state"); state.addTextNode ("CA"); SOAPElement zip = propertyAddress.addChildElement ("zip"); zip.addTextNode ("94521"); SOAPElement listPrice = listingElement.addChildElement ("listPrice"); listPrice.addTextNode ("25000"); 

Merk at du legger til eiendommens unike ID som attributt til propertyListing element. Videre kvalifiserer du propertyListing element med en QNameeller navneområdebevisst navn.

Du kan legge til vedlegg i SOAP-meldingen på flere måter. I dette eksemplet oppretter du først elementer for å betegne eiendommens fremre og indre bilder. Hver har en href attributt som angir vedleggets innholds-ID:

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

For å enkelt feste de nødvendige bildefilene til meldingen, bruk a javax.activation.DataHandler objekt fra JavaBeans Activation Framework. DataHandler kan automatisk oppdage datatypen som sendes til den, og den kan derfor automatisk tilordne den aktuelle MIME-innholdstypen til vedlegget:

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

Alternativt kan du passere en Gjenstand, sammen med riktig MIME-type, til createAttachmentPart (). Den metoden ligner den første. Internt vil SAAJ-implementeringen sannsynligvis se etter en DataContentHandler for å håndtere den spesifiserte MIME-typen. Hvis den ikke finner en passende behandler, createAttachmentPart () vil kaste en IllegalArgumentException:

URL url2 = ny URL ("file: ///export/files/pic2.jpg"); Image 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