Simple Object Access Protocol (SOAP) er en generell beskrivelse. SOAP og webtjenester

10 svar

WSDL er et XML-dokument som beskriver en webtjeneste. Det betyr faktisk et webtjenestedefinisjonsspråk.

SOAP er en XML-basert protokoll som lar informasjon utveksles over en bestemt protokoll (som HTTP eller SMTP) mellom applikasjoner. Den står for Simple Object Access Protocol og bruker XML som meldingsformat for å overføre informasjon.

REST er en arkitektonisk stil av nettverkssystemer og står for representasjonstilstandsoverføring. Det er ikke en standard i seg selv, men bruker standarder som HTTP, URL, XML, etc.

Hver gang noen nevner SOAP / WSDL, tenker jeg på objektene og klassene som er definert i xml ...

"Du bruker SOAP akkurat som enhver PHP-klasse. Men i dette tilfellet eksisterer ikke klassen på det lokale applikasjonsfilsystemet, men på en ekstern vert som er tilgjengelig via http." ... "Hvis vi tenker på å bruke SOAP- tjeneste som en annen PHP-klasse, så er WSDL-dokumentet en liste over alle tilgjengelige metoder og egenskaper for klassen."

Og hver gang noen snakker om REST, tenker jeg på HTTP-kommandoer (forespørselsmetoder) som POST, GET og DELETE

Eksempel: Enkelt sagt, hvis du har en kalkulatorwebtjeneste.

WSDL: WSDL snakker om funksjonaliteten du kan implementere eller eksponere for klienten. For eksempel: legge til, fjerne, trekke fra osv.

SOAP: der du, ved å bruke SOAP, faktisk utfører handlinger som doDelete (), doSubtract (), doAdd (). Så SOAP og WSDL er epler og appelsiner. Vi trenger ikke å sammenligne dem. De har begge hver sin funksjonalitet.

Hvorfor bruker vi SOAP og WSDL: for å utveksle uavhengige data på plattformen.

EDIT: I vanlig hverdag:

WSDL: Når vi går til restauranten, ser vi menyelementene, dette er WSDL.

Fullmaktsklasser: Nå, etter å ha sett på menyelementene, komponerer vi tankene våre (behandler vårt syn på rekkefølgen): Så i utgangspunktet lager vi proxy-klassene basert på WSDL-dokumentet.

SÅPE: Så når vi faktisk bestiller mat basert på menyen: det antydes at vi bruker proxy-klasser for å påkalle servicemetodene som gjøres med SOAP. :)

SOAP → SOAP (Simple Object Access Prototype) er applikasjonsprotokolllaget bygget for maskin-til-maskin-kommunikasjon. Protokollen definerer standardregler. Alle parter som bruker en bestemt protokoll må følge reglene i protokollen. I likhet med TCP vikles den av ved transportlaget. SOAP vil bli forstått på applikasjonsnivå (enhver applikasjon som støtter SOAP - Axis2, .Net).

WSDL -> SOAP-melding består av SoapEnevelope-> SoapHeader og SoapBody. Den definerer ikke hva meldingsformatet vil være? hvilke alle transporter (HTTP, JMS) støttes? uten denne informasjonen. Det er vanskelig for enhver klient som ønsker å bruke en bestemt webtjeneste å lage en SOAP-melding. Selv om de gjør det, vil de ikke være sikre på at det vil fungere hele tiden. WSDL er en livredder. WSDL (Web Services Description Language) definerer operasjoner, meldingsformater og transportdata for en SOAP-melding.

REST -> REST (View State Transfer) er transportbasert. I motsetning til SOAP, som er handlingsorientert, handler REST mer om ressurser. REST finner ressurser ved å bruke en URL (eksempel -http: // (serverAddress) / ansatte / ansattnummer / 12345) og avhenger av transportprotokollen (med HTTP-GET, POST, PUT, DELETE, ...) for handlinger for å ta ressurser . REST-tjenesten finner en ressurs basert på URL-en og utfører en handling basert på transporthandlingsverbet. Det er mer en arkitektonisk stil og konvensjoner.

SOAP står for Simple (sic) Object Access Protocol. Det var ment å foreta eksterne prosedyrekall på eksterne objekter ved å sende XML over HTTP.

WSDL er et Web Services Description Language. En forespørsel som slutter på ".wsdl"-endepunkt vil resultere i at en XML-melding sendes som beskriver forespørselen og svaret som bruken kan forvente. Den beskriver kontrakten mellom tjenesten og klienten.

REST bruker HTTP til å sende meldinger til tjenester.

SOAP er en spesifikasjon, REST er en stil.

Du kommer ikke til å "bare" forstå noe komplisert.

WSDL er et XML-basert språk for å beskrive en webtjeneste. Den beskriver meldinger, operasjoner og transportnettverksinformasjon som brukes av tjenesten. Disse nettjenestene bruker vanligvis SOAP, men kan bruke andre protokoller.

WSDL kan leses av et program og kan derfor brukes til å generere hele eller deler av klientkoden som kreves for å starte nettjenesten. Dette er hva det vil si å kalle SOAP-orienterte webtjenester "selvbeskrivende".

REST er ikke relatert til WSDL i det hele tatt.

Wikipedia sier, "The Web Services Description Language er et XML-basert språk som gir en modell for å beskrive webtjenester." Med andre ord refererer WSDL til webtjenesten som javadoc refererer til java-biblioteket.

En veldig fin ting med WSDL er imidlertid at programvare kan generere klient og server ved å bruke WSDL.

Hva er SOAP?

SOAP står for Simple Object Access Protocol. Jeg håper, etter å ha lest artikkelen, vil du bare bli forvirret: "Hva er dette merkelige navnet?"

SOAP i sin nåværende form er en Remote Procedure Call (RPC)-metode over et nettverk. (Ja, det brukes også til å overføre dokumenter som XML, men vi hopper over det for nå.)

La oss finne ut av det. Tenk deg at du har en tjeneste som returnerer en aksjekurs for et gitt aksjesymbol. Den sender data til Nasdaq-nettstedet og genererer ønsket resultat basert på returnert HTML. Videre, for å tillate andre utviklere å bruke den i sine applikasjoner, gjør du denne tjenesten til en komponent som finner informasjon om sitater via Internett. Det fungerer utmerket helt til Nasdaq en dag endrer oppsettet på sidene sine. Du må revidere hele logikken til komponenten og sende oppdateringer til alle utviklere som bruker den. Og de må på sin side sende oppdateringer til alle brukerne sine. Hvis dette skjer mer eller mindre med jevne mellomrom, kan du få ganske mange fiender blant andre utviklere. Og med programmerere, som du vet, er vitser dårlige. Du vil vel ikke ta et bilde av din elskede katt fra makuleringsmaskinen i morgen?

Hva å gjøre? La oss se ... alt du trenger er å gi en funksjon som godtar en ticker (av strengtypen) og returnerer en aksjekurs (av flytende eller dobbel type). Så ville det ikke vært enklere å bare la utviklerne kalle denne funksjonen over Internett på en eller annen måte? Fint! Også nyheter for meg, det er COM og Corba, og Java, som har gjort dette i årevis ... som er sant, men disse metodene er ikke feilfrie. Ekstern COM-konfigurasjon er ikke triviell. I tillegg er det så mange porter å åpne i brannmuren at du ikke kan få nok av en øl-systemadministrator. Ja, og du må glemme brukerne av alle operativsystemer unntatt Windows. Men Linux-brukere er også noen ganger interessert i utvekslingen.

Selv om det ser ut til at ikke alt er tapt for Linux-brukere hvis de bruker DCOM, er det mer her: http://www.idevresource.com/com/library/res/articles/comonlinux.asp.

Det er ikke mye jeg kan si om Corba og Java, så som en øvelse inviterer jeg leserne til å finne ulempene med disse tilnærmingene.

SOAP er en standard som lar deg beskrive en slik ekstern påkalling og hvilken type resultatet vil bli returnert. Dermed må du plassere funksjonen din i en applikasjon tilgjengelig over nettverket og motta anrop i form av SOAP-pakker. Etter det validerer du inndataene, kjører funksjonen din og returnerer resultatet i en ny SOAP-pakke. Hele prosessen kan kjøres over HTTP, slik at du ikke trenger å åpne en haug med porter i brannmuren din. Enkelt, ikke sant?

Hva handler denne artikkelen om

Dette er den første i en serie SOAP-artikler som vi skriver hos Agni Software. I denne artikkelen vil jeg prøve å gi deg en forståelse av hva SOAP er og hvordan du skriver en applikasjon som kommuniserer med en SOAP-server.

Såpe og XML

Hvis SOAP fortsatt virker enkelt for deg, la oss legge til XML. Nå, i stedet for funksjonsnavnet og parameterne, får vi en ganske kompleks XML-konvolutt, som om den er designet for å forvirre deg. Men ikke ha det travelt med å bli redd. Det kommer mer, og du må se det store bildet for å forstå kompleksiteten til SOAP.
Hvis du ikke vet hva XML er, les først artikkelen min om XML her: http://www.agnisoft.com/white_papers/xml_delphi.asp.

Alle SOAP-pakker er i XML-format. Hva betyr det? La oss se. Ta en titt på denne funksjonen (Pascal):
funksjon GetStockQuote (Symbol: streng): dobbel; Ser bra ut, men problemet er at det er Pascal. Hva er bruken av denne enkle definisjonen for en Java-utvikler? Eller for noen som jobber med VB? Vi trenger noe som alle forstår, også VB-programmerere. Så gi dem XML som inneholder samme informasjon (parametere, anførselsverdier osv.). Du lager en SOAP-pakke, som i hovedsak er et kall til funksjonen din, pakket inn i XML slik at enhver applikasjon på hvilken som helst plattform kan forstå den. La oss nå se hvordan SOAP-anropet vårt ser ut:
xmlns: xsi = "http://www.w3.org/1999/XMLSchema-instance"
xmlns: xsd = "http://www.w3.org/1999/XMLSchema">


IBM


Informativ, ikke sant? SOAP er forenklet foran øynene våre. Ok, vitser til side. Nå skal jeg prøve å forklare deg hvordan du forstår denne SOAP-samtalen.

Dekoding av tagger

Den første taggen som fanger oppmerksomheten din er ... Denne taggen er den ytre omslaget til en SOAP-pakke, som inneholder noen få navneområdeerklæringer som vi ikke er spesielt interessert i, men som er veldig viktige for et hvilket som helst programmeringsspråk eller parser. Navneområder er definert slik at påfølgende prefikser som "SOAP-ENV:" eller "xsd:" analyseres av parseren.

Neste merke er ... (Vi savnet en merkelapp som ikke er presentert her - ... Det er ikke i dette spesielle eksemplet, men hvis du vil lese mer om det, se SOAP-spesifikasjonen her: http://www.w3.org/TR/SOAP/). stikkord faktisk inneholder SOAP-anropet.

Den neste taggen på listen er ... Tagnavnet, GetStockQuote, er funksjonen som skal kalles. I SOAP-terminologi kalles dette en operasjon. Dermed er GetStockQuote en operasjon som må utføres. ns1 er et navneområde som peker til urn: xmethods-quotes i vårt tilfelle.

En lyrisk digresjon om navnerom: Navneområder gir muligheten til å kvalifisere en XML-tag. Du kan for eksempel ikke ha to variabler med samme navn i en prosedyre, men er de i to forskjellige prosedyrer, oppstår det ingen problemer. Dermed er en prosedyre et navneområde siden alle navn i den er unike. På samme måte er XML-koder omfattet av navneområder, så gitt navneområdet og kodenavnet kan du identifisere det unikt. Vi vil definere navneområdet som en URI for å skille vår NS1 fra copycats. I eksemplet ovenfor er NS1 et alias som peker på urn: xmethods-quotes.

Legg også merke til encodingStyle-attributtet - dette attributtet definerer hvordan SOAP-anropet serialiseres.

Inne i merkelappen inneholder parametere. I vårt enkleste tilfelle har vi bare én parameter - taggen ... Legg merke til denne linjen ved siden av taggen:
xsi: type = "xsd: streng"
Dette er omtrent hvordan typer defineres i XML. (Merk hvor smart jeg brukte ordet "om" for å generalisere om teknologien, som kan endre seg når artikkelen er publisert). Hva betyr dette nøyaktig: typen som er definert i xsi-navneområdet, som du la merke til er definert i taggen - xsd: streng. Og dette er i sin tur en streng, definert i xsd-navneområdet, igjen definert tidligere. (Jeg er sikker på at advokatene bare ville bli begeistret for dette).

Inne i merkelappen angitt med "IBM". Dette er verdien av symbolparameteren til GetStockQuote-funksjonen.

Vel, til slutt, som anstendige mennesker, stengte vi alle taggene.

Så vi fant ut SOAP-pakken som definerer kallet til SOAP-serveren. Og SOAP-serveren bruker XML-parsere, en rød knapp og MIR-romstasjonen for å dekode denne samtalen og fastslå at du trenger en aksjekurs. Han finner umiddelbart det ønskede tilbudet og returnerer det til deg i dette skjemaet:
SOAP-ENV: encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" />


34.5


Etter å ha rullet ut SOAP-konvolutten, revet av båndene og raslet i omslaget, finner vi ut at IBM-aksjekursen er 34,5.

De fleste kommersielle servere vil returnere mye mer informasjon, for eksempel i hvilken valuta og til hvilken pris den siste aksjen ble kjøpt. Og aksjekursen ville kanskje vært mer presis.

På denne måten vet vi hva SOAP-serveren forventer og hva den vil returnere. Så HVORDAN sender du denne informasjonen? Enhver transport kan brukes. Den mest uthevede er HTTP. Jeg vil ikke gå inn på detaljene om HTTP, for de som ikke vet - dette er hva nettleseren din bruker for å kommunisere med nettstedene du besøker.

Den nødvendige HTTP-forespørselen vil se omtrent slik ut:
POST / StockQuote HTTP / 1.1
Vert: www.stockquoteserver.com

Innhold-Lengde: nnnn
SOAPAction: "Some-URI"

Såpeforespørselspakken her ... Det eneste andre som er verdt å merke seg er SOAPAction-overskriften. Denne overskriften angir formålet med forespørselen og er påkrevd. Hver SOAP-server kan ha et ubegrenset antall funksjoner og kan bruke SOAPAction-overskriften til å bestemme hvilken funksjon som kalles. Brannmurer og multipleksere kan også filtrere innhold basert på denne overskriften.

SOAP-svaret fra HTTP-serveren vil se slik ut:
HTTP / 1.1 200 OK
Innholdstype: tekst / xml; tegnsett = "utf-8"
Innhold-Lengde: nnnn

Såperesponspakke her ... Hvorfor HTTP? For det første trenger ikke nettverksadministratorer å åpne opp en haug med separate porter for SOAP-anrop ... webserveren kan håndtere anropene uten problemer. Port 80 er vanligvis åpen for alle for å motta innkommende forespørsler. En annen fordel er utvidbarheten til webservere som bruker CGI, ISAPI og andre native moduler. Denne utvidelsesmuligheten lar deg skrive en modul som håndterer SOAP-forespørsler uten å påvirke annet nettinnhold.

Det er alt

Forhåpentligvis hjalp denne artikkelen med å kaste lys over SOAP. Hvis du fortsatt er her og vil lese mer om dette emnet, kan du besøke forfatterens nettsted: http://www.agnisoft.com/soap

hatter 23. juli 2013 kl. 13:09

Skrive en SOAP klient-server-applikasjon i PHP

  • PHP
  • Opplæringen

Hei alle sammen!
Det har seg sånn at i det siste har jeg begynt å drive med utvikling av webtjenester. Men i dag handler ikke temaet om meg, men om hvordan vi kan skrive vår XML Web Service basert på SOAP 1.2-protokollen.

Jeg håper at etter å ha lest emnet, vil du være i stand til å uavhengig:

  • skrive din egen server-side implementering av en webapplikasjon;
  • skrive din egen klient-side implementering av en webapplikasjon;
  • skrive din egen webtjenestebeskrivelse (WSDL);
  • sende av klienten arrays av samme type data til serveren.
Som du kanskje har gjettet, vil all magien gjøres ved hjelp av PHP og de innebygde SoapClient- og SoapServer-klassene. Tjenesten for å sende sms vil fungere som en kanin.

1 Problemstilling

1.1 Grenser

I begynnelsen foreslår jeg å ta for oss resultatet som vi vil oppnå på slutten av emnet. Som annonsert ovenfor vil vi skrive en tjeneste for å sende sms-meldinger, eller mer presist vil vi motta meldinger fra forskjellige kilder via SOAP-protokollen. Etter det vil vi vurdere i hvilken form de kommer til serveren. Selve prosessen med å sette meldinger i kø for videre sending til leverandøren, er dessverre utenfor rammen av dette innlegget av mange grunner.

1.2 Hvilke data vil vi endre?

Flott, vi har bestemt oss for grensene! Det neste trinnet som må gjøres er å bestemme hvilke data vi skal utveksle mellom serveren og klienten. Om dette emnet foreslår jeg å ikke være klok på lenge og umiddelbart svare på hovedspørsmålene for meg selv:
  • Hva er minimumsmengden data som må sendes til serveren for å sende en SMS-melding til en abonnent?
  • Hva er minimumsmengden data som må sendes fra serveren for å tilfredsstille klientens behov?
Noe sier meg at dette krever at du sender følgende:
  • mobilnummer også
  • SMS-tekst.
I prinsippet er disse to egenskapene nok til å sende, men jeg ser umiddelbart for meg et tilfelle når en SMS med bursdagshilsen kommer til deg klokken 15 om morgenen, eller 16! I dette øyeblikket vil jeg være veldig takknemlig for alle for ikke å bli glemt om meg! Derfor vil vi også sende til serveren og
  • datoen for sending av sms-meldingen.
Det neste jeg vil sende til serveren er
  • Type melding.
Denne parameteren er valgfri, men den kan være veldig nyttig for oss i tilfelle vi raskt trenger å fortelle sjefen hvor mange av kundene våre vi "gjorde fornøyde" med nyhetene våre, og også trekke noen fine statistikker på denne poengsummen.

Og likevel har jeg glemt noe! Hvis vi reflekterer litt mer, så er det verdt å merke seg at en klient kan sende både én sms og flere av dem til serveren om gangen. Med andre ord kan én datapakke inneholde fra én til uendelig meldinger.

Som et resultat får vi at for å sende en SMS-melding, trenger vi følgende data:

  • mobilnummer,
  • SMS-tekst,
  • tidspunkt for å sende en SMS-melding til en abonnent,
  • type melding.

Vi har svart på det første spørsmålet, nå er det nødvendig å svare på det andre spørsmålet. Og kanskje jeg vil tillate meg selv et lite hakk. Derfor vil vi bare sende boolske data fra serveren, hvis verdi har følgende betydning:

  • TRUE - pakken nådde serveren, ble autentisert og kom inn i køen for å sendes til sms-leverandøren
  • FALSE - i alle andre tilfeller

Dette avslutter beskrivelsen av problemstillingen! Og til slutt, la oss komme ned til det mest interessante - la oss finne ut hvilket merkelig beist denne SÅPEN er!

2 Hva er SOAP med?

Generelt planla jeg i utgangspunktet ikke å skrive noe om hva SOAP er og ønsket å begrense meg til lenker til w3.org-siden med nødvendige spesifikasjoner, samt lenker til Wikipedia. Men helt til slutt bestemte jeg meg for å skrive en kort referanse om denne protokollen.

Og jeg vil begynne min historie med det faktum at denne datautvekslingsprotokollen tilhører en undergruppe av protokoller basert på det såkalte RPC (Remote Procedure Call) paradigmet, det motsatte av dette er REST (Representational State Transfer). Du kan lese mer om dette i Wikipedia, lenker til artikler ligger helt til slutt i emnet. Fra disse artiklene må vi forstå følgende: "RPC-tilnærmingen lar deg bruke en liten mengde nettverksressurser med et stort antall metoder og en kompleks protokoll. Med en REST-tilnærming er antallet metoder og kompleksiteten til protokollen strengt begrenset, noe som kan føre til et stort antall individuelle ressurser." Det vil si at i forhold til oss betyr dette at når det gjelder RPC-tilnærmingen på nettstedet, vil det alltid være én inngang (lenke) til tjenesten og hvilken prosedyre man skal ringe for å behandle innkommende data vi overfører sammen med dataene, mens med REST-tilnærmingen på vår siden har mange innganger (lenker), som hver aksepterer og behandler kun visse data. Hvis noen som leser vet hvordan de skal forklare forskjellen i disse tilnærmingene enda enklere, så husk å skrive i kommentarene!

Det neste vi trenger å vite om SOAP er at denne protokollen bruker samme XML som en transport, noe som på den ene siden er veldig bra, fordi umiddelbart inn i vårt arsenal kommer all kraften til stabelen med teknologier basert på dette markup-språket inn i vårt arsenal, nemlig XML-Schema - et språk for å beskrive strukturen til et XML-dokument (takk til Wikipedia!), som tillater automatisk validering av data kommer til serveren fra klienter.

Og så, nå vet vi at SOAP er en protokoll som brukes til å implementere eksterne prosedyrekall, og den bruker XML som transport! Hvis du leser artikkelen på Wikipedia, så kan du også lære derfra at den kan brukes på toppen av enhver applikasjonslagsprotokoll, og ikke bare sammen med HTTP (dessverre vil vi i dette emnet kun vurdere SOAP over HTTP). Og vet du hva jeg liker best med alt dette? Hvis det ikke er noen gjetninger, så vil jeg gi deg et hint - SOAP! ... Likevel, ingen gjetninger dukket opp? ... Du har definitivt lest artikkelen på Wikipedia? ... Generelt vil jeg ikke torturere deg videre . Derfor vil jeg gå rett til svaret: «SOAP (fra den engelske Simple Object Access Protocol - enkel protokoll tilgang til gjenstander; opp til spesifikasjon 1.2) ". De mest bemerkelsesverdige tingene med denne linjen er i kursiv! Jeg vet ikke hvilke konklusjoner du har trukket fra alt dette, men jeg ser følgende - siden denne protokollen ikke kan kalles "enkel" (og tilsynelatende er enig i dette selv i w3), siden versjon 1.2 har den sluttet å bli dechiffrert på en eller annen måte ! Og det ble kjent som SOAP, bare SOAP-periode.

Vel, ok, jeg ber om unnskyldning, det skled litt til siden. Som jeg skrev tidligere, brukes XML som transport, og pakkene som går mellom klienten og serveren kalles SOAP-konvolutter. Hvis vi vurderer den generaliserte strukturen til konvolutten, vil den virke veldig kjent for deg siden ligner strukturen til en HTML-side. Den har en hoveddel - Konvolutt som inkluderer seksjoner Overskrift og Kropp eller Feil... V Kropp data overføres og det er en obligatorisk del av konvolutten, mens Overskrift er valgfritt. V Overskrift autorisasjon kan overføres, eller andre data som ikke er direkte relatert til inndataene til nettjenesteprosedyrene. Om Feil det er ikke noe spesielt å fortelle, bortsett fra at det kommer til klienten fra serveren i tilfelle feil.

Dette avslutter min oversiktshistorie om SOAP-protokollen (vi vil vurdere mer detaljert selve konvoluttene og deres struktur når klienten og serveren vår endelig lærer å kjøre dem inn i hverandre) og en ny begynner - om SOAP-ledsageren kalt WSDL(Web Services Description Language). Ja, ja, dette er nettopp det som skremmer de fleste av oss fra selve forsøket på å ta og implementere API-en vår på denne protokollen. Som et resultat finner vi vanligvis opp hjulet vårt på nytt med JSON for transport. Så hva er WSDL? WSDL er et språk for å beskrive nettjenester og få tilgang til dem, basert på XML (c) Wikipedia-språket. Hvis du fra denne definisjonen ikke forstår hele den hellige betydningen av denne teknologien, så vil jeg prøve å beskrive den med mine egne ord!

WSDL er designet slik at våre klienter kan kommunisere med serveren normalt. For å gjøre dette er følgende informasjon beskrevet i filen med filtypen "* .wsdl":

  • Hvilke navneområder ble brukt,
  • Hvilke dataskjemaer ble brukt,
  • Hvilke typer meldinger forventer netttjenesten fra klienter,
  • Hvilke data tilhører hvilke prosedyrer for nettjenesten,
  • Hvilke prosedyrer inneholder nettjenesten,
  • Hvordan klienten skal ringe netttjenesteprosedyrene,
  • Til hvilken adresse skal klientens anrop sendes.
Som du kan se, er denne filen hele webtjenesten. Ved å spesifisere adressen til WSDL-filen i klienten, vil vi vite alt om enhver webtjeneste! Som et resultat trenger vi ikke å vite absolutt ingenting om hvor selve nettjenesten befinner seg. Du trenger bare å vite plasseringen til WSDL-filen! Snart vil vi lære at SOAP ikke er så forferdelig som det er malt (c) russiske ordtak.

3 Introduksjon til XML-skjema

Nå vet vi mye om hva SOAP er, hva som er inne i den, og vi har en oversikt over teknologistabelen rundt den. Siden SOAP først og fremst er en måte for interaksjon mellom en klient og en server, og XML-markeringsspråk brukes som transport for det, vil vi i denne delen forstå litt hvordan data automatisk valideres ved hjelp av XML-skjemaer.

Hovedoppgaven til skjemaet er å beskrive strukturen til dataene vi skal behandle. Alle data i XML-skjemaer er delt inn i enkel(skalær) og kompleks(strukturer) typer. Enkle typer inkluderer slike typer som:

  • linje,
  • Nummer,
  • boolsk verdi,
  • Dato.
Noe veldig enkelt som ikke har utvidelser inni. Deres antipode er komplekse komplekse typer. Det enkleste eksemplet på en kompleks type som alle kan tenke på er gjenstander. For eksempel en bok. Boken består av egenskaper: forfatter, tittel, pris, ISBN-nummer etc. Og disse egenskapene kan på sin side være både enkle typer og komplekse. Og XML-skjemaets oppgave er å beskrive det.

Jeg foreslår at du ikke går langt og skriver et XML-skjema for sms-meldingen vår! Nedenfor er xml-beskrivelsen av sms-meldingen:

71239876543 Testmelding 2013-07-20T12: 00:00 12
Vårt komplekse typeskjema vil se slik ut:


Denne oppføringen lyder som følger: vi har en variabel " beskjed"Type" Beskjed"Og det er en kompleks type som heter" Beskjed", som består av et sekvensielt sett med elementer" telefon"Type streng, « tekst"Type streng, « Dato"Type dato tid, « type"Type desimal... Disse typene er enkle og er allerede definert i skjemabeskrivelsen. Gratulerer! Vi har nettopp skrevet vårt første XML-skjema!

Jeg tror at betydningen av elementene " element"og" kompleksType"Alt har blitt mer eller mindre klart for deg, så vi vil ikke fokusere på dem lenger og vil umiddelbart gå over til komponistelementet" sekvens". Når vi bruker komponistelementet " sekvens»Vi informerer om at elementene som er inkludert i den alltid må være plassert i rekkefølgen som er angitt i diagrammet, og også alle er påkrevd. Men fortvil ikke! Det er ytterligere to komponistelementer i XML-skjemaer: " valg"og" alle". Komponist" valg"Informerer om at det skal være ett av elementene oppført i den, og komponisten" alle"- enhver kombinasjon av de oppførte elementene.

Som du husker, i den første delen av emnet, ble vi enige om at fra én til uendelig sms-meldinger kan overføres i en pakke. Derfor foreslår jeg å forstå hvordan slike data er deklarert i XML-skjemaet. Den generelle strukturen til pakken kan se slik ut:

71239876543 Testmelding 1 2013-07-20T12: 00:00 12 71239876543 Testmelding N 2013-07-20T12: 00:00 12
Opplegget for en så kompleks type vil se slik ut:


Den første blokken inneholder den kjente erklæringen av den komplekse typen " Beskjed". Hvis du har lagt merke til, så i alle enkle typer inkludert i " Beskjed", Nye kvalifiserende attributter er lagt til" minForekommer"og" maxForekommer". Som du kanskje gjetter ut fra navnet, den første ( minForekommer) indikerer at denne sekvensen må inneholde minst ett element av typen " telefon», « tekst», « Dato"og" type", Mens den neste ( maxForekommer) attributtet erklærer for oss at det er høyst ett slikt element i sekvensen vår. Som et resultat, når vi skriver skjemaene våre for data, får vi det bredeste valget når det gjelder tilpasning!

Den andre blokken i diagrammet erklærer elementet " meldingsliste"Type" Meldingsliste". Det er klart at " Meldingsliste"Er en kompleks type som inneholder minst ett element" beskjed", Men det maksimale antallet slike elementer er ikke begrenset!

4 Skrive din egen WSDL

Husker du at WSDL er vår nettjeneste? Håper du husker! Mens vi skriver det, vil vår lille webtjeneste flyte på den. Derfor foreslår jeg å ikke jukse.

Generelt, for at alt skal fungere riktig, må vi overføre en WSDL-fil med riktig MIME-type til klienten. For å gjøre dette må du konfigurere webserveren din tilsvarende, nemlig angi MIME-typen for filer med filtypen "* .wsdl" til følgende linje:

Applikasjon / wsdl + xml
Men i praksis sender jeg vanligvis HTTP-headeren " tekst / xml»:

Header ("Innholdstype: tekst / xml; tegnsett = utf-8");
og alt fungerte utmerket!

Jeg vil med en gang advare deg om at vår enkle nettjeneste vil ha en ganske imponerende beskrivelse, så ikke vær redd, for det meste av teksten er obligatorisk, og når den først er skrevet, kan du hele tiden kopiere fra en nettjeneste til en annen!

Siden WSDL er XML, må du skrive om det direkte i den aller første linjen. Rotelementet til filen må alltid hete " definisjoner»:


Vanligvis består WSDL av 4-5 hovedblokker. Den aller første blokken er definisjonen av webtjenesten, eller med andre ord inngangspunktet.


Det står her at vi har en tjeneste som heter - " SmsService". I utgangspunktet kan du endre alle navnene i WSDL-filen til hva du vil. de spiller absolutt ingen rolle.

Etter det kunngjør vi at i vår nettjeneste " SmsService"Det er et inngangspunkt (" port ") kalt" SmsServicePort". Det er til dette inngangspunktet at alle forespørsler fra klienter til serveren vil bli sendt. Og vi indikerer i elementet " adresse»En lenke til behandlerfilen som godtar forespørsler.

Etter at vi har definert en nettjeneste og angitt et inngangspunkt for den, må vi binde de støttede prosedyrene til den:


For dette er det oppført hvilke operasjoner og i hvilken form de vil bli kalt. De. for havnen" SmsServicePort"En binding er definert under navnet" SmsServiceBinding", som har typen samtale" rpc"Og HTTP brukes som overføringsprotokoll (transport). Derfor har vi her indikert at vi vil foreta et RPC-kall over HTTP. Etter det beskriver vi hvilke prosedyrer ( operasjon) støttes i nettjenesten. Vi vil bare støtte én prosedyre - " Send tekstmelding". Gjennom denne prosedyren vil våre fantastiske meldinger bli sendt til serveren! Etter at prosedyren er kunngjort, er det nødvendig å indikere i hvilken form dataene vil bli overført. I dette tilfellet er det spesifisert at standard SOAP-konvolutter skal brukes.

Etter det må vi binde prosedyren til meldinger:


For å gjøre dette spesifiserer vi at vår "binding" er av typen " SmsServicePortType"Og i elementet" portType»Med navn av samme type indikerer vi bindingen av prosedyrer til meldinger. Og så vil den innkommende meldingen (fra klient til server) få navnet " sendSmsRequest", Og utgående (fra server til klient)" sendSmsResponse". Som alle navn i WSDL, er navnene på innkommende og utgående meldinger vilkårlige.

Nå må vi beskrive selve meldingene, dvs. innkommende og utgående:


For å gjøre dette legger vi til elementene " beskjed"Med navnene" sendSmsRequest"og" sendSmsResponse"henholdsvis. I dem indikerer vi at en konvolutt skal komme til inngangen, hvis struktur tilsvarer datatypen " Be om". Etter det returnerer serveren en konvolutt som inneholder datatypen - " Respons».

Nå må vi gjøre den minste tingen - legg til en beskrivelse av disse typene til WSDL-filen vår! Og hvordan tror du WSDL beskriver inngående og utgående data? Jeg tror at du allerede har forstått alt for lenge siden og sa til deg selv det ved hjelp av XML-skjemaer! Og du vil ha helt rett!


Du kan gratulere oss! Vår første WSDL er skrevet! Og vi er et skritt nærmere å nå dette målet.
Deretter skal vi se på hva PHP gir oss for å utvikle våre egne distribuerte applikasjoner.

5 Vår første SOAP-server

Tidligere skrev jeg at vi skal bruke den innebygde SoapServer-klassen for å lage en SOAP-server i PHP. For at alle videre handlinger skal skje på samme måte som min, må du justere PHP-en din litt. Mer spesifikt må du sørge for at du har "php-soap"-utvidelsen installert. Hvordan du legger den på webserveren din er best å lese på den offisielle PHP-siden (se listen over referanser).

Etter at alt er installert og konfigurert, må vi opprette en fil i rotmappen til hostingen din " smsservice.php"Med følgende innhold:

setClass ("SoapSmsGateWay"); // Start serveren $ server-> handle ();
Jeg håper at det ikke er behov for å forklare hva som er over linjen med "ini_set"-funksjonen. Fordi der bestemmes det hvilke HTTP-hoder vi skal sende fra serveren til klienten og miljøet er konfigurert. I linjen med "ini_set" deaktiverer vi hurtigbufringen av WSDL-filen slik at endringene våre i den umiddelbart trer i kraft på klienten.

Nå kommer vi til serveren! Som du kan se, er hele SOAP-serveren bare tre linjer lang! I den første linjen oppretter vi en ny forekomst av SoapServer-objektet og sender den til konstruktøren adressen til vår WSDL-webtjenestebeskrivelse. Nå vet vi at den vil være plassert i roten til hostingen i en fil med det selvforklarende navnet " smsservice.wsdl.php". I den andre linjen forteller vi SOAP-serveren hvilken klasse som må trekkes for å behandle konvolutten mottatt fra klienten og returnere konvolutten med svaret. Som du kanskje har gjettet, er det i denne klassen vår eneste metode vil bli beskrevet. Send tekstmelding... På den tredje linjen starter vi serveren! Det er det, serveren vår er klar! Som jeg gratulerer oss alle med!

Nå må vi lage en WSDL-fil. For å gjøre dette kan du enten kopiere innholdet fra forrige seksjon, eller ta deg friheten og "mal" det litt:

"; ?> / "xmlns: xs =" http://www.w3.org/2001/XMLSchema "xmlns: soap12 =" http://schemas.xmlsoap.org/wsdl/soap12/ "xmlns: http =" http: // schemas.xmlsoap.org/wsdl/http/ "name =" SmsWsdl "xmlns =" ​​​​http://schemas.xmlsoap.org/wsdl/ "> /"> /smsservice.php "/>
På dette stadiet bør den resulterende serveren passe oss fullstendig, fordi vi kan logge konvolutter som kommer til den og deretter rolig analysere innkommende data. For at vi skal motta noe på serveren trenger vi en klient. Så la oss gjøre det!

6 SOAP-klient på vei

Først av alt må vi lage en fil der vi skal skrive klienten. Som vanlig vil vi lage den ved roten til verten og gi den navnet " klient.php", Og inne skriver vi følgende:

meldingsliste = ny meldingsliste (); $ req-> messageList-> message = ny melding (); $ req-> messageList-> message-> phone = "79871234567"; $ req-> messageList-> message-> text = "Testmelding 1"; $ req-> messageList-> message-> date = "2013-07-21T15: 00: 00.26"; $ req-> messageList-> message-> type = 15; $ client = new SoapClient ("http: // ($ _SERVER [" HTTP_HOST "]) / smsservice.wsdl.php, array (" soap_version "=> SOAP_1_2)); var_dump ($ klient-> sendSms ($ req));
La oss beskrive objektene våre. Da vi skrev WSDL, beskrev den tre enheter for konvolutten som kommer inn på serveren: Be om, Meldingsliste og Beskjed... Følgelig klasser Be om, Meldingsliste og Beskjed er refleksjoner av disse enhetene i vårt PHP-skript.

Etter at vi har definert objektene, må vi lage et objekt ( $ req), som vi sender til serveren. Etter det er det to mest kjære linjer for oss! Vår SOAP-klient! Tro det eller ei, men dette er nok til at meldinger fra klienten begynner å strømme inn på serveren vår, så vel som at serveren vår skal kunne motta og behandle dem! I den første av dem oppretter vi en forekomst av SoapClient-klassen og sender adressen til plasseringen av WSDL-filen til konstruktøren, og i parameterne indikerer vi eksplisitt at vi vil jobbe med SOAP versjon 1.2. På neste linje kaller vi metoden Send tekstmelding gjenstand $ klient og umiddelbart vise resultatet i nettleseren.
La oss kjøre den og se hva vi endelig har fått!

Følgende objekt ble returnert til meg fra serveren:

Objekt (stdClass) public "status" => boolsk sann
Og dette er flott, fordi nå vet vi med sikkerhet at serveren vår fungerer og ikke bare fungerer, men også kan returnere noen verdier til klienten!

La oss nå ta en titt på loggen som vi holder på serversiden! I den første delen av den ser vi rådataene som kom til serveren:

79871234567 Testmelding 1 2013-07-21T15: 00: 00.26 15
Dette er konvolutten. Nå vet du hvordan det ser ut! Men det vil neppe være interessant for oss å konstant beundre det, så la oss deserialisere objektet fra loggfilen og se om alt er bra med oss:

Objekt (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "phone" => streng "79871234567" (lengde = 11) offentlig "tekst" => streng "Testmelding 1 "(lengde = 37) offentlig" dato "=> streng" 2013-07-21T15: 00: 00.26 "(lengde = 22) offentlig" type "=> streng" 15 "(lengde = 2)
Som du kan se, ble objektet deserialisert riktig, som jeg vil gratulere oss alle med! Neste, noe mer interessant venter på oss! Vi vil nemlig sende av klienten til serveren ikke én sms-melding, men en hel haug (for å være mer presis, tre så mange)!

7 Sende komplekse objekter

La oss tenke på hvordan vi kan overføre en hel haug med meldinger til serveren i en pakke? Sannsynligvis den enkleste måten ville være å organisere arrayet inne i messageList-elementet! La oss gjøre dette:

// opprette et objekt for å sende til serveren $ req = new Request (); $ req-> messageList = ny meldingsliste (); $ msg1 = ny melding (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testmelding 1"; $ msg1-> date = "2013-07-21T15: 00: 00.26"; $ msg1-> type = 15; $ msg2 = ny melding (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testmelding 2"; $ msg2-> date = "2014-08-22T16: 01: 10"; $ msg2-> type = 16; $ msg3 = ny melding (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testmelding 3"; $ msg3-> date = "2014-08-22T16: 01: 10"; $ msg3-> type = 17; $ req-> messageList-> message = $ msg1; $ req-> messageList-> message = $ msg2; $ req-> messageList-> message = $ msg3;
Loggene våre indikerer at følgende pakke kom fra en klient:

79871234567 Testmelding 1 2013-07-21T15: 00: 00.26 15 79871234567 Testmelding 2 2014-08-22T16: 01:10 16 79871234567 Testmelding 3 2014-08-22T16: 01:10 17
Hvilket tull, sier du? Og du vil ha rett på en måte, fordi vi har nettopp lært at hvilket objekt som forlot klienten, så i absolutt samme form kom det til serveren vår i form av en konvolutt. SMS-meldinger ble imidlertid ikke serialisert til XML slik vi trengte dem - de måtte pakkes inn i elementer beskjed, ikke i Struktur... La oss nå se i hvilken form et slikt objekt kommer til metoden Send tekstmelding:

Objekt (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "Struct" => array (størrelse = 3) 0 => objekt (stdClass) public "phone" => streng "79871234567" (lengde = 11) offentlig "tekst" => streng "Testmelding 1" (lengde = 37) offentlig "dato" => streng "2013-07-21T15: 00: 00.26" (lengde = 22) offentlig " type "=> streng" 15 "(lengde = 2) 1 => objekt (stdClass) offentlig" telefon "=> streng" 79871234567 "(lengde = 11) offentlig" tekst "=> streng" Testmelding 2 "(lengde = 37) offentlig "dato" => streng "2014-08-22T16: 01: 10" (lengde = 19) offentlig "type" => streng "16" (lengde = 2) 2 => objekt (stdClass) offentlig "telefon "=> streng" 79871234567 "(lengde = 11) offentlig" tekst "=> streng" Testmelding 3 "(lengde = 37) offentlig" dato "=> streng" 2014-08-22T16: 01: 10 "(lengde = 19) offentlig "type" => streng "17" (lengde = 2)
Hva gir denne kunnskapen oss? Bare at veien vi har valgt ikke er riktig og vi har ikke fått svar på spørsmålet - "Hvordan kan vi få riktig datastruktur på serveren?" Men jeg foreslår at du ikke fortviler og prøver å tilpasse vårt utvalg til typen en gjenstand:

$ req-> messageList-> message = (objekt) $ req-> messageList-> message;
I dette tilfellet vil vi motta en ny konvolutt:

79871234567 Testmelding 1 2013-07-21T15: 00: 00.26 15 79871234567 Testmelding 2 2014-08-22T16: 01:10 16 79871234567 Testmelding 3 2014-08-22T16: 01:10 17
Kom i metode Send tekstmelding objektet har følgende struktur:

Objekt (stdClass) public "messageList" => objekt (stdClass) public "message" => objekt (stdClass) public "BOGUS" => array (størrelse = 3) 0 => objekt (stdClass) public "phone" => streng "79871234567" (lengde = 11) offentlig "tekst" => streng "Testmelding 1" (lengde = 37) offentlig "dato" => streng "2013-07-21T15: 00: 00.26" (lengde = 22) offentlig " type "=> streng" 15 "(lengde = 2) 1 => objekt (stdClass) offentlig" telefon "=> streng" 79871234567 "(lengde = 11) offentlig" tekst "=> streng" Testmelding 2 "(lengde = 37) offentlig "dato" => streng "2014-08-22T16: 01: 10" (lengde = 19) offentlig "type" => streng "16" (lengde = 2) 2 => objekt (stdClass) offentlig "telefon "=> streng" 79871234567 "(lengde = 11) offentlig" tekst "=> streng" Testmelding 3 "(lengde = 37) offentlig" dato "=> streng" 2014-08-22T16: 01: 10 "(lengde = 19) offentlig "type" => streng "17" (lengde = 2)
Som for meg, så "fra en endring i stedene av vilkårene - summen endres ikke" (c). Hva TULL, hva Struktur- målet er ennå ikke nådd av oss! Og for å oppnå det, må vi sørge for at i stedet for disse uforståelige navnene, vises vårt innfødte beskjed... Men hvordan man oppnår dette, vet ikke forfatteren ennå. Derfor er det eneste vi kan gjøre å kvitte oss med den ekstra beholderen. Med andre ord vil vi nå gjøre det slik at i stedet for beskjed ble til TULL! For å gjøre dette, la oss endre objektet som følger:

// opprette et objekt for å sende til serveren $ req = new Request (); $ msg1 = ny melding (); $ msg1-> phone = "79871234567"; $ msg1-> text = "Testmelding 1"; $ msg1-> date = "2013-07-21T15: 00: 00.26"; $ msg1-> type = 15; $ msg2 = ny melding (); $ msg2-> phone = "79871234567"; $ msg2-> text = "Testmelding 2"; $ msg2-> date = "2014-08-22T16: 01: 10"; $ msg2-> type = 16; $ msg3 = ny melding (); $ msg3-> phone = "79871234567"; $ msg3-> text = "Testmelding 3"; $ msg3-> date = "2014-08-22T16: 01: 10"; $ msg3-> type = 17; $ req-> messageList = $ msg1; $ req-> messageList = $ msg2; $ req-> messageList = $ msg3; $ req-> messageList = (objekt) $ req-> messageList;
Hva om vi er heldige og det riktige navnet vil bli trukket fra diagrammet? For å gjøre dette, la oss se på den mottatte konvolutten:

79871234567 Testmelding 1 2013-07-21T15: 00: 00.26 15 79871234567 Testmelding 2 2014-08-22T16: 01:10 16 79871234567 Testmelding 3 2014-08-22T16: 01:10 17
Ja, miraklet skjedde ikke! TULL– vi vinner ikke! Kom inn Send tekstmelding objektet i dette tilfellet vil se slik ut:

Objekt (stdClass) public "messageList" => objekt (stdClass) public "BOGUS" => array (størrelse = 3) 0 => objekt (stdClass) public "phone" => streng "79871234567" (lengde = 11) public " tekst "=> streng" Testmelding 1 "(lengde = 37) offentlig" dato "=> streng" 2013-07-21T15: 00: 00.26 "(lengde = 22) offentlig" type "=> streng" 15 "(lengde) = 2) 1 => objekt (stdClass) offentlig "telefon" => streng "79871234567" (lengde = 11) offentlig "tekst" => streng "Testmelding 2" (lengde = 37) offentlig "dato" => streng " 2014-08-22T16: 01: 10 "(lengde = 19) offentlig" type "=> streng" 16 "(lengde = 2) 2 => objekt (stdClass) offentlig" telefon "=> streng" 79871234567 "(lengde = 11) offentlig "tekst" => streng "Testmelding 3" (lengde = 37) offentlig "dato" => streng "2014-08-22T16: 01: 10" (lengde = 19) offentlig "type" => streng " 17" (lengde = 2)
Som de sier - "Nesten"! På dette (litt triste) notatet foreslår jeg å gradvis runde av og trekke noen konklusjoner for meg selv.

8 Konklusjon

Endelig kom vi hit! La oss definere hva du kan gjøre nå:
  • du kan skrive den nødvendige WSDL-filen for webtjenesten din;
  • du kan skrive din egen klient uten problemer som kan kommunisere med serveren ved hjelp av SOAP-protokollen;
  • du kan skrive din egen server som kommuniserer med omverdenen via SOAP;
  • du kan sende arrays av objekter av samme type til serveren fra klienten din (med noen begrensninger).
I tillegg gjorde vi noen oppdagelser for oss selv i løpet av vår lille forskning:
  • den opprinnelige SoapClient-klassen kan ikke serialisere datastrukturer av samme type ordentlig i XML;
  • når du serialiserer en matrise til XML, oppretter den et ekstra element kalt Struktur;
  • når du serialiserer et objekt til XML, oppretter det et ekstra element kalt TULL;
  • TULL mindre ondskap enn Struktur på grunn av det faktum at konvolutten er mer kompakt (ingen ekstra navneområder legges til i XML-overskriften til konvolutten);
  • Dessverre validerer ikke SoapServer-klassen automatisk konvoluttdataene med vårt XML-skjema (kanskje andre servere ikke gjør det).

Emnetittelen er egentlig et spørsmål, siden Selv vet jeg ikke hva det er, og for første gang vil jeg prøve å jobbe med det innenfor rammen av denne artikkelen. Det eneste jeg kan garantere at koden nedenfor vil fungere, men mine setninger vil bare være antagelser og gjetninger om hvordan jeg selv forstår alt dette. Så la oss gå ...

Introduksjon

Vi må starte med hva konseptet webtjenester ble skapt for. Da dette konseptet dukket opp, eksisterte det allerede teknologier i verden som tillot applikasjoner å samhandle på avstand, der ett program kunne kalle en metode i et annet program, som samtidig kunne startes på en datamaskin i en annen by eller til og med et land. Alt dette er forkortet til RPC (Remote Procedure Calling). Eksempler inkluderer CORBA-teknologier, og for Java - RMI (Remote Method Invoking). Og alt ser ut til å være bra i dem, spesielt i CORBA, tk. du kan jobbe med det i alle programmeringsspråk, men noe manglet fortsatt. Jeg tror at ulempen med CORBA er at den fungerer gjennom noen av sine egne nettverksprotokoller i stedet for enkel HTTP, som vil krype gjennom hvilken som helst brannmur. Tanken bak webtjenesten var å lage en RPC som skulle feste seg i HTTP-pakker. Slik begynte utviklingen av standarden. Hva er de grunnleggende konseptene for denne standarden:
  1. SÅPE... Før du kaller en ekstern prosedyre, må du beskrive denne samtalen i en SOAP XML-fil. SOAP er ganske enkelt en av de mange XML-markeringene som brukes i webtjenester. Alt vi ønsker å sende et sted via HTTP blir først omgjort til en XML SOAP-beskrivelse, deretter legges det inn i en HTTP-pakke og sendes til en annen datamaskin på nettverket via TCP/IP.
  2. WSDL... Det er en webtjeneste, dvs. et program hvis metoder kan kalles eksternt. Men standarden krever at det legges ved en beskrivelse til dette programmet, som sier at «ja, du tar ikke feil – dette er egentlig en nettjeneste og du kan kalle slike og slike metoder fra den». Denne beskrivelsen er representert av en annen XML-fil som har et annet format, nemlig WSDL. De. WSDL er bare en XML-beskrivelsesfil for en webtjeneste og ingenting annet.
Hvorfor spør du så kort? Kan du ikke få flere detaljer? Sannsynligvis kan du det, men for dette må du vende deg til bøker som Mashnin T. "Java Web Services". Der, for de første 200 sidene, er det en detaljert beskrivelse av hver tag i SOAP- og WSDL-standardene. Bør jeg gjøre det? Etter min mening, nei, tk. alt dette genereres automatisk i Java, og alt du trenger å gjøre er å skrive innholdet i metodene som skal kalles eksternt. Så i Java var det et slikt API som JAX-RPC. Hvis noen ikke vet, når de sier at Java har et slikt og slikt API, betyr det at det er en pakke med et sett med klasser som kapsler inn den aktuelle teknologien. JAX-RPC utviklet seg fra versjon til versjon i lang tid og utviklet seg til slutt til JAX-WS. WS står åpenbart for WebService, og du tror kanskje at dette er en enkel omdøping av RPC til et populært ord i disse dager. Dette er ikke tilfelle, siden Nå har webtjenester gått bort fra den opprinnelige ideen og lar deg ikke bare ringe eksterne metoder, men også enkelt sende dokumentmeldinger i SOAP-format. Hvorfor dette er nødvendig, vet jeg ikke ennå, svaret er neppe «i tilfelle, plutselig blir det nødvendig». Selv vil jeg gjerne lære av mer erfarne kamerater. Og det siste, så var det også JAX-RS for de såkalte RESTful webtjenestene, men dette er et tema for en egen artikkel. På dette tidspunktet kan introduksjonen avsluttes, fordi neste gang skal vi lære å jobbe med JAX-WS.

Generell tilnærming

Webtjenester har alltid en klient og en server. Serveren er vår nettjeneste og kalles noen ganger et endepunkt (som endepunktet der SOAP-meldinger fra klienten går). Vi må gjøre følgende:
  1. Beskriv grensesnittet til vår nettjeneste
  2. Implementer dette grensesnittet
  3. Start vår nettjeneste
  4. Skriv en klient og ring den nødvendige webtjenestemetoden eksternt
En webtjeneste kan lanseres på forskjellige måter: enten ved å beskrive en klasse med en hovedmetode og starte webtjenesten direkte, som en server, eller distribuere den til en server som Tomcat eller en hvilken som helst annen. I det andre tilfellet starter vi ikke selv en ny server og åpner ikke en annen port på datamaskinen, men forteller bare Tomcat servlet-beholderen at "vi skrev nettjenesteklassene her, publiser dem, vær så snill, slik at alle som kontakter du kan bruke nettjenesten vår. Uavhengig av metode for lansering av nettjenesten, vil vi ha samme klient.

Server

La oss starte IDEA og lage et nytt prosjekt Opprett nytt prosjekt... La oss skrive inn et navn HelloWebService og trykk på knappen Neste, deretter knappen Bli ferdig... I mappen src opprette en pakke ru.javarush.ws... I denne pakken vil vi lage HelloWebService-grensesnittet: package ru. javarush. ws; // dette er merknader, dvs. en måte å markere våre klasser og metoder, // relatert til nettjenesteteknologi importer javax. jws. WebMethod; importer javax. jws. Nettjeneste; importer javax. jws. såpe. SOAP-binding; // vi sier at grensesnittet vårt vil fungere som en webtjeneste@Nettjeneste // si at webtjenesten vil bli brukt til å ringe metoder@SOAPBinding (stil = SOAPBinding. Style. RPC) offentlig grensesnitt HelloWebService ( // vi sier at denne metoden kan kalles eksternt@WebMethod offentlig streng getHelloString (strengnavn); ) I denne koden er WebService- og WebMethod-klassene såkalte merknader og gjør ikke annet enn å merke grensesnittet vårt og dets metode som en webtjeneste. Det samme gjelder for SOAPBinding-klassen. Den eneste forskjellen er at SOAPBinding er en parametermerknad. I dette tilfellet brukes stilparameteren med en verdi som sier at webtjenesten ikke vil fungere gjennom dokumentmeldinger, men som en klassisk RPC, dvs. å kalle metoden. La oss implementere logikken til grensesnittet vårt og lage en HelloWebServiceImpl-klasse i pakken vår. Forresten, merker jeg at slutten av klassen i Impl er en konvensjon i Java, ifølge hvilken implementeringen av grensesnitt er betegnet på denne måten (Impl - fra ordet implementering, dvs. implementering). Dette er ikke et krav og du står fritt til å navngi klassen hva du vil, men reglene for god form krever det: pakke ru. javarush. ws; // samme merknad som når du beskriver grensesnittet, importer javax. jws. Nettjeneste; // men brukt her med endpointInterface-parameter, // spesifiserer det fullt kvalifiserte klassenavnet på grensesnittet til vår nettjeneste@WebService (endepunktgrensesnitt = "ru.javarush.ws.HelloWebService") offentlig klasse HelloWebServiceImpl implementerer HelloWebService (@Override public String getHelloString (String name) ( // bare returnere en hilsen returner "Hei," + navn + "!" ; )) La oss starte vår webtjeneste som en uavhengig server, dvs. uten involvering av noen Tomcat og applikasjonsservere (dette er et emne for en egen diskusjon). For å gjøre dette, i prosjektstrukturen i mappen src la oss lage en pakke ru.javarush.endpoint, og i den lage en HelloWebServicePublisher-klasse med en hovedmetode: pakke ru. javarush. endepunkt; // klasse for å starte en webserver med webtjenester importer javax. xml. ws. endepunkt; // klasse av vår nettjeneste import ru. javarush. ws. HelloWebServiceImpl; offentlig klasse HelloWebServicePublisher (public static void main (String... args) ( // start webserveren på port 1986 // og på adressen spesifisert i det første argumentet, // start webtjenesten som ble sendt i det andre argumentet Endepunkt. publisere ( "http: // localhost: 1986 / wss / hei", ny HelloWebServiceImpl ()); )) La oss nå kjøre denne klassen ved å klikke Shift + F10... Ingenting vises i konsollen, men serveren kjører. Du kan bekrefte dette ved å skrive inn linjen http: // localhost: 1986 / wss / hello?Wsdl i nettleseren. Siden som åpnes, beviser på den ene siden at en webserver (http: //) har startet på datamaskinen vår (localhost) på port 1986, og viser på den andre siden WSDL-beskrivelsen av vår webtjeneste. Hvis du stopper applikasjonen, blir beskrivelsen utilgjengelig, så vel som selve webtjenesten, så vi vil ikke gjøre dette, men fortsette med å skrive klienten.

Kunde

I prosjektmappen src lag en pakke ru.javarush.client, og i den HelloWebServiceClient-klassen med hovedmetoden: pakke ru. javarush. klient; // nødvendig for å få wsdl-beskrivelse og gjennom den // nå selve webtjenesten importer java. nett. URL; // en slik kjøring vil skje når du arbeider med et URL-objekt importer java. nett. MisformetURLEunntak; // klasser for å analysere xml-ku med wsdl-beskrivelse // og nå servicekoden i den importer javax. xml. navneområde. QName; importer javax. xml. ws. Service; // grensesnittet til vår nettjeneste (vi trenger mer) import ru. javarush. ws. HelloWebService; offentlig klasse HelloWebServiceClient (public static void main (String args) kaster MalformedURLEexception ( // opprett en lenke til wsdl-beskrivelse URL url = ny url ( "http: // localhost: 1986 / wss / hallo? wsdl") ; // Vi ser på parametrene til neste konstruktør i den aller første taggen i WSDL-beskrivelsen - definisjoner // se det første argumentet i targetNamespace-attributtet // se det andre argumentet i navnattributtet QName qname = new QName ("http: //ws.site/", "HelloWebServiceImplService"); // Nå kan vi nå servicekoden i wsdl-beskrivelsen, Service service = Service. opprette (url, qname); // og deretter opp til den nestede portkoden, slik at // få en lenke til et webtjenesteobjekt eksternt fra oss HelloWebService hei = tjeneste. getPort (HelloWebService. klasse); // Hurra! Nå kan du ringe den eksterne metoden System. ute. println (hei. getHelloString ("CodeGym")); )) Jeg ga maksimale kommentarer til koden i oppføringen. Jeg har ingenting å legge til, så kjør (Shift + F10). Vi bør se teksten i konsollen: Hei, CodeGym! Hvis du ikke så den, har du sannsynligvis glemt å starte nettjenesten.

Konklusjon

I dette emnet ble en kort utflukt til webtjenester presentert. Igjen, mye av det jeg har skrevet er mine gjetninger om hvordan det fungerer, og bør derfor ikke stoles for mye på. Jeg vil være takknemlig om kunnskapsrike folk korrigerer meg, for da lærer jeg noe. UPD.

Simple Object Access Protocol (SOAP) er en XML-basert protokoll som definerer reglene for overføring av meldinger over Internett mellom ulike applikasjonssystemer. Den brukes hovedsakelig for eksterne prosedyreanrop. SOAP ble opprinnelig designet med en forventning om at den skulle fungere "over" HTTP (for å gjøre det enklere å integrere SOAP i webapplikasjoner), men andre transportprotokoller som SMTP kan nå brukes.

Anta at du oppretter en applikasjonstjeneste på Internett; forbrukere samhandler med denne tjenesten ved å gi informasjon til den. Serverne dine behandler dataene og returnerer resultatene til forbrukerne. Hva er den beste måten å støtte kommunikasjon med systemet på?

Du kan opprette en tilpasset klient-/serverapplikasjon og kreve at forbrukere bruker et tilpasset klientprogram for å få tilgang til tjenesten din. Men hvis du seriøst skal finne deg selv i internettbransjen, må du lage en klient som fungerer på alle mulige klientplattformer - Windows, Macintosh, Unix, Linux osv. Du må med andre ord skrive mange forskjellige kunder.

Hva synes du om å bruke nettet? En slik løsning er selvfølgelig ganske akseptabel, men den er strengt knyttet til implementeringen av nettleseren, og igjen må du lage en infrastruktur for å sende og motta innkommende og utgående informasjon, samt format og pakkedata for slike et bytte. Du kan velge Java eller ActiveX for å implementere komplekse applikasjoner, men da vil noen brukere nekte tjenestene dine på grunn av klart overvurderte båndbreddekrav og utilstrekkelig beskyttelse.

Alt som kreves er en enkel protokoll som gjør det enkelt å pakke applikasjonsdata og overføre dem over nettet ved hjelp av innholdstilpasset XML. Dermed sikrer det at både avsender og mottaker enkelt kan tolke innholdet i enhver melding. Samtidig, ved å bruke webprotokollen HTTP som transport, vil det være mulig å eliminere behovet for å redusere nivået av brannmurbeskyttelse.

Den godt dokumenterte Simple Object Access Protocol (SOAP) er en enkel "lim"-protokoll som verter kan eksternt påkalle applikasjonsobjekter og returnere resultater. SOAP tilbyr et minimalt sett med betingelser som tillater en applikasjon å overføre meldinger: klienten kan sende en melding for å kalle et programobjekt, og serveren kan returnere resultatene av det anropet.

SOAP er ganske enkelt: meldinger er XML-dokumenter som inneholder SOAP-kommandoer. Mens SOAP teoretisk sett kan være bundet til enhver applikasjonstransportprotokoll, brukes den vanligvis sammen med HTTP.

Kennard Scribner, en av forfatterne av boken Forstå SOAP: Den autoritative løsningen(Macmillan USA, 2000) sier SOAP fungerer ved å transformere informasjonen som kreves for å påkalle en metode (som argumentverdier og transaksjons-IDer) til XML.

Dataene er innkapslet i HTTP eller en annen transportprotokoll og overføres til destinasjonen, som vanligvis er serveren. Denne serveren trekker ut SOAP-dataene fra pakken, utfører den nødvendige behandlingen og returnerer resultatene som et SOAP-svar.

Scribner bemerket at SOAP fungerer som en ekstern prosedyreanropsprotokoll, omtrent som Remote Method Invocation-protokollen i Java eller General Inter-ORB Protocol i CORBA.

Fordi HTTP og XML brukes nesten overalt, sier Scribner at SOAP uten tvil er den mest skalerbare RPC-protokollen som finnes. SOAP er ikke designet for å fungere som en komplett objektarkitektur.

SOAP erstatter ikke Remote Method Invocation Protocol i Java, den distribuerte komponentobjektmodellen og CORBA; han foreslår regler om at alle disse modellene kan brukes. SOAP er ikke en komplett løsning. Den støtter ikke objektaktivering eller -beskyttelse. I følge Scribner har SOAP-designere "tillit på at brukerne vil legge til denne koden selv," og bygger på toppen av SOAP, i stedet for å gjøre den til en del av selve protokollen.

Figuren viser et eksempel hentet fra SOAP 1.1-spesifikasjonen der verten ber om tilbudstjenesten for verdien av en bestemt aksje. SOAP-forespørselen er innebygd i HTTP POST, og forespørselsteksten spesifiserer forespørselstypen og parameteren - aksjesymbolet. Svaret gir også et XML-objekt innkapslet i et HTTP-svar med en enkelt returverdi (34.5 i dette tilfellet).

SOAP-funksjoner

Med SOAP kan utviklere lage webtjenester like raskt som de raskt kan skrive SOAP-meldinger for å starte programmer for eksisterende applikasjoner, og deretter legge til disse applikasjonene på enkle websider. Men i tillegg har utviklere muligheten til å bruke SOAP-anrop i dedikerte applikasjoner og lage applikasjoner som kan porteres til andres nettsider, og dermed unngå den tidkrevende og kostbare utviklingsprosessen.

I følge Mark Stever, en annen forfatter av Understanding SOAP, er dette nettopp målet Microsoft forfølger med sin kommende .Net-plattform. "Det er her SOAP kommer ut i all sin prakt. Det gir utviklere en virkelig flott mulighet til å bygge applikasjoner uten bryet med potensielle inkompatibiliteter, sier han.

SÅPE eksempel

Følgende eksempel illustrerer en SOAP-forespørsel kalt GetLastTradePrice som lar en klient sende en forespørsel om de siste kursene for en bestemt aksje.

POST / StockQuote HTTP / 1.1
Vert: www.stockquoteserver.com
Innholdstype: tekst / xml; tegnsett = "utf-8"
Innhold-lengde: nnnn
SOAPAction:"Noen-URI"

De første fem linjene (en del av HTTP-headeren) spesifiserer meldingstypen (POST), vert, innholdstype og lengde, og SOAPAction-headeren identifiserer formålet med SOAP-forespørselen. Selve SOAP-meldingen er et XML-dokument med en SOAP-konvolutt først, deretter et XML-element som spesifiserer SOAP-navneområdet og eventuelle attributter. En SOAP-konvolutt kan inneholde en overskrift (men ikke i dette tilfellet) etterfulgt av en SOAP-tekst. I vårt eksempel inneholder brødteksten GetLastTradePrice-forespørselen og aksjesymbolet som de siste kursene er forespurt for. Svaret på denne forespørselen kan se slik ut.

HTTP / 1.1 200 OK
Innholdstype: tekst / xml; tegnsett = "utf-8"
Innhold-lengde: nnnn

Igjen er de tre første linjene en del av HTTP-overskriften; Selve SOAP-meldingen består av en konvolutt som inneholder svaret på den opprinnelige forespørselen, merket med GetLastTradePriceResponse, og inkluderer en returverdi, i dette tilfellet 34.5.