Protocol SOAP și servicii web. Servicii web XML. Protocolul SOAP

Titlul subiectului este într-adevăr o întrebare, pentru că... Eu însumi nu știu ce este și pentru prima dată voi încerca să lucrez cu el în cadrul acestui articol. Singurul lucru pe care îl pot garanta este că codul prezentat mai jos va funcționa, dar frazele mele vor fi doar presupuneri și presupuneri despre cum înțeleg eu însumi toate acestea. Deci, hai să mergem...

Introducere

Trebuie să începem cu motivul pentru care a fost creat conceptul de servicii web. Până la apariția acestui concept în lume, deja existau tehnologii care permiteau aplicațiilor să interacționeze la distanță, unde un program putea apela la o metodă într-un alt program, care putea fi lansat pe un computer situat într-un alt oraș sau chiar țară. Toate acestea sunt prescurtate ca RPC (Remote Procedure Calling). Exemplele includ tehnologiile CORBA și pentru Java - RMI (Remote Method Invoking). Și totul pare să fie bine în ei, mai ales în CORBA, pentru că... Puteți lucra cu el în orice limbaj de programare, dar încă lipsea ceva. Cred că dezavantajul CORBA este că funcționează prin unele dintre ele protocoale de rețeaîn loc de HTTP simplu, care se va potrivi prin orice firewall. Ideea serviciului web a fost de a crea un RPC care să fie inserat în pachetele HTTP. Astfel a început dezvoltarea standardului. Care sunt conceptele de bază ale acestui standard:
  1. SĂPUN. Înainte de a apela o procedură de la distanță, trebuie să descrieți acest apel în fișier XML e format SOAP. SOAP este pur și simplu unul dintre numeroasele markupuri XML care sunt utilizate în serviciile web. Tot ceea ce dorim să trimitem undeva prin HTTP este mai întâi convertit într-o descriere XML SOAP, apoi introdus într-un pachet HTTP și trimis către un alt computer din rețea prin TCP/IP.
  2. WSDL. Există un serviciu web, adică un program ale cărui metode pot fi apelate de la distanță. Dar standardul cere ca acest program să fie însoțit de o descriere care spune că „da, ai dreptate - acesta este într-adevăr un serviciu web și poți apela astfel de metode din el”. Această descriere este reprezentată de un alt fișier XML, care are un alt format și anume WSDL. Aceste. WSDL este doar un fișier XML care descrie un serviciu web și nimic mai mult.
De ce întrebi atât de scurt? Nu poți fi mai precis? Probabil că este posibil, dar pentru a face acest lucru va trebui să apelați la cărți precum T. Mashnin, „Java Web Services”. Acolo, pe primele 200 de pagini, există o descriere detaliată a fiecărei etichete a standardelor SOAP și WSDL. Merită făcut? După părerea mea, nu, pentru că... toate acestea sunt create automat în Java și trebuie doar să scrieți conținutul metodelor care ar trebui să fie apelate de la distanță. Deci, un API precum JAX-RPC a apărut în Java. Dacă cineva nu știe, când spune că Java are așa și așa API, înseamnă că există un pachet cu un set de clase care încapsulează tehnologia în cauză. JAX-RPC a evoluat de-a lungul timpului de la versiune la versiune și în cele din urmă a devenit JAX-WS. WS înseamnă, în mod evident, WebService și s-ar putea să credeți că aceasta este pur și simplu o redenumire a RPC ca un cuvânt popular în zilele noastre. Acest lucru nu este adevărat, pentru că Acum serviciile web s-au îndepărtat de ideea originală și vă permit nu numai să apelați metode de la distanță, ci și să trimiteți pur și simplu mesaje de document în format SOAP. Nu știu încă de ce este nevoie de acest lucru; este puțin probabil ca răspunsul aici să fie „doar în cazul în care este necesar”. Eu însumi aș dori să învăț de la camarazi mai experimentați. Și, în sfârșit, a apărut JAX-RS pentru așa-numitele servicii web RESTful, dar acesta este subiectul unui articol separat. Introducerea se poate încheia aici, pentru că... În continuare vom învăța să lucrăm cu JAX-WS.

Abordare generală

În serviciile web există întotdeauna un client și un server. Serverul este serviciul nostru web și uneori este numit punctul final (cum ar fi, punctul final, unde ajung mesajele SOAP de la client). Trebuie să facem următoarele:
  1. Descrieți interfața serviciului nostru web
  2. Implementați această interfață
  3. Lansați serviciul nostru web
  4. Scrieți un client și apelați de la distanță metoda de serviciu web dorită
Serviciul web poate fi lansat în moduri diferite: fie descrieți o clasă cu o metodă principală și rulați serviciul web direct ca server, fie implementați-l pe un server precum Tomcat sau oricare altul. În al doilea caz, nu ne lansăm server nouși nu deschidem un alt port pe computer, ci pur și simplu spunem containerului de servlet Tomcat că „am scris clase de servicii web aici, vă rugăm să le publicați, astfel încât toți cei care vă contactează să poată folosi serviciul nostru web”. Indiferent de metoda de lansare a serviciului web, vom avea acelasi client.

Server

Să lansăm IDEA și să creăm proiect nou Creați un proiect nou. Să indicăm numele HelloWebServiceși apăsați butonul Următorul, apoi butonul Termina. Într-un folder src hai să creăm un pachet ru.javarush.ws. În acest pachet vom crea interfața HelloWebService: pachet ru. javarush. ws; // acestea sunt adnotări, i.e. o modalitate de a ne marca clasele și metodele, // în legătură cu tehnologia serviciilor web import javax. jws. WebMethod; import javax. jws. WebService; import javax. jws. săpun. SAPUNLegare; // spunem că interfața noastră va funcționa ca un serviciu web@WebService // spunem că serviciul web va fi folosit pentru a apela metode@SOAPBinding (style = SOAPBinding. Style. RPC) interfață publică HelloWebService ( // spunem că această metodă poate fi apelată de la distanță@WebMethod public String getHelloString(Nume șir) ; ) În acest cod, clasele WebService și WebMethod sunt așa-numitele adnotări și nu fac altceva decât să marcheze interfața noastră și metoda acesteia ca serviciu web. Același lucru este valabil și pentru clasa SOAPBinding. Singura diferență este că SOAPBinding este o adnotare cu parametri. În acest caz, parametrul de stil este utilizat cu o valoare care indică faptul că serviciul web va funcționa nu prin mesaje de document, ci ca un RPC clasic, de exemplu. a apela o metodă. Să implementăm logica interfeței noastre și să creăm o clasă HelloWebServiceImpl în pachetul nostru. Apropo, observ că terminarea unei clase cu Impl este o convenție în Java, conform căreia implementarea interfețelor este astfel desemnată (Impl - din cuvântul implementare, adică implementare). Aceasta nu este o cerință și sunteți liber să denumiți clasa cum doriți, dar bunele maniere o cer: pachet ru. javarush. ws; // aceeași adnotare ca atunci când descrieți interfața, import javax. jws. WebService;// dar aici este folosit cu parametrul endpointInterface,// indicând Numele complet clasa de interfață a serviciului nostru web @WebService(endpointInterface=„ru.javarush.ws.HelloWebService” src) clasa publică HelloWebServiceImpl implementează HelloWebService ( @Override public String getHelloString (nume șir) ( // returnează doar salutul returnează "Bună ziua, " + nume + "!" ; ) ) Să lansăm serviciul nostru web ca server independent, adică. fără participarea niciunui Tomcat și a serverelor de aplicații (acesta este un subiect pentru o discuție separată). Pentru a face acest lucru, în structura proiectului din folder import ru. javarush. ws. HelloWebServiceImpl; clasă publică HelloWebServicePublisher ( public static void main (String... args) ( // porniți serverul web pe portul 1986 // și la adresa specificată în primul argument,// pornește serviciul web transmis în al doilea argument Punct final. publica(„http://localhost:1986/wss/hello” , nou HelloWebServiceImpl () );) ) Acum să rulăm această clasă făcând clic

Shift+F10

. Nu va apărea nimic în consolă, dar serverul rulează. Puteți verifica acest lucru tastând linia http://localhost:1986/wss/hello?wsdl în browser. Pagina care se deschide, pe de o parte, demonstrează că avem un server web (http://) care rulează pe portul 1986 pe computerul nostru (localhost) și, pe de altă parte, arată o descriere WSDL a serviciului nostru web. Dacă opriți aplicația, descrierea va deveni indisponibilă, la fel ca și serviciul web în sine, așa că nu vom face acest lucru, ci vom trece la scrierea clientului. src Client În folderul de proiect Să creăm un pachet ru.javarush.client , iar în el clasa HelloWebServiceClient cu metoda principală: pachet ru. javarush. client;// necesar pentru a obține descrierea wsdl și prin ea // ajunge la serviciul web în sine import java. net. URL; // această excepție va apărea când lucrați cu un obiect URL import java. net. MalformedURLException;// clase pentru a analiza xml cu descrierea wsdl // și ajungeți la eticheta de serviciu din ea import javax. xml. spatiu de nume. QName; import javax. xml. ws. Serviciu; // interfața serviciului nostru web (avem nevoie de mai mult) import ru. javarush. ws. HelloWebService; clasă publică HelloWebServiceClient ( public static void main (String args) aruncă MalformedURLException () ; // creează un link către descrierea wsdl URL URL = URL nou ( „http://localhost:1986/wss/hello?wsdl” // Ne uităm la parametrii următorului constructor din prima etichetă a descrierii WSDL - definiții // uită-te la primul argument din atributul targetNamespace // uită-te la al 2-lea argument, atributul numelui QName qname = nou QName ("http://ws.site/" , "HelloWebServiceImplService" ); // Acum putem ajunge la eticheta de serviciu în descriere wsdl Service service = Service. create (url, qname); Sistem. afară. println (bună ziua. getHelloString ("JavaRush"));

) ) Am dat maxim de comentarii la codul din listare. Nu am nimic de adăugat, așa că hai să alergăm (Shift+F10). Ar trebui să vedem textul în consolă: Bună ziua, JavaRush! Dacă nu l-ați văzut, atunci probabil ați uitat să porniți serviciul web.

Concluzie Acest subiect a oferit o scurtă excursie în serviciile web. Încă o dată, voi spune că o mare parte din ceea ce am scris este presupunerea mea cu privire la modul în care funcționează și, prin urmare, nu ar trebui să aveți prea multă încredere în mine. Aș fi recunoscător dacă oamenii cunoscători mă corectează, pentru că atunci voi învăța ceva.
  • UPD.

Tutorial
Salutare tuturor! S-a întâmplat ca înîn ultima vreme

Am început să dezvolt servicii web. Dar astăzi subiectul nu este despre mine, ci despre cum putem scrie propriul nostru serviciu web XML bazat pe protocolul SOAP 1.2.

  • Sper că după ce ai citit subiectul vei putea:
  • scrieți propria implementare de server a unei aplicații web;
  • scrieți propria implementare client a unei aplicații web;
  • scrieți propria descriere a serviciului web (WSDL);
trimite matricele client de același tip de date către server.

După cum probabil ați ghicit, toată magia se va face folosind PHP și clasele încorporate SoapClient și SoapServer. Iepurele nostru va fi un serviciu de trimitere de mesaje SMS.

1 Enunțarea problemei

1.1 Limite La început, îmi propun să ne ocupăm de rezultatul pe care îl vom obține la finalul subiectului. După cum am anunțat mai sus, vom scrie un serviciu pentru trimiterea de mesaje SMS și, mai precis, vom primi mesaje de la surse diferite prin protocolul SOAP. După care, vom lua în considerare sub ce formă vin pe server. Însuși procesul de a pune în coadă mesaje pentru a fi trimise în continuare către furnizor, din păcate, depășește domeniul de aplicare al a acestei postări

din multe motive.

1.2 Ce date vom schimba?
  • Super, ne-am hotărât limitele! Următorul pas care trebuie făcut este să decidem ce date vom schimba între server și client. Pe acest subiect, vă sugerez să nu despărțiți părul prea mult timp și să răspundeți imediat la întrebările principale:
  • Ce date minime trebuie trimise către server pentru a trimite un mesaj SMS unui abonat?
Ce date minime trebuie trimise de la server pentru a satisface nevoile clientului?
  • Ceva îmi spune că pentru asta trebuie să trimiți următoarele:
  • numărul de telefon mobil și
În principiu, aceste două caracteristici sunt suficiente pentru trimitere, dar îmi imaginez imediat cazul unui SMS cu felicitări de ziua de naștere care vin la tine la ora 3 dimineața, sau 4! În acest moment, voi fi foarte recunoscător tuturor pentru că nu au uitat de mine! Prin urmare, vom trimite și către server și
  • data trimiterii mesajului SMS.
Următorul lucru pe care aș dori să-l trimit pe server este:
  • Tipul mesajului.
Acest parametru nu este obligatoriu, dar ne poate fi foarte util dacă trebuie să îi spunem rapid șefului câți dintre clienții noștri ne-am „încântat” de știrile noastre și, de asemenea, să tragem câteva statistici frumoase pe această temă.

Și totuși, am uitat ceva! Dacă reflectăm puțin mai mult, este de remarcat faptul că clientul poate trimite fie un mesaj SMS, fie câteva dintre ele la server la un moment dat. Cu alte cuvinte, un pachet de date poate conține de la unu la infinit mesaje.

Drept urmare, obținem că pentru a trimite un mesaj SMS avem nevoie de următoarele date:

  • numarul de telefon mobil,
  • text mesaj SMS,
  • ora trimiterii mesajului SMS către abonat,
  • tipul mesajului.

Am răspuns la prima întrebare, acum trebuie să răspundem la a doua întrebare. Și poate îmi voi permite să fac un pic de încurcătură. Prin urmare, de pe server vom trimite doar date booleene, a căror semnificație are următoarea semnificație:

  • TRUE – pachetul a ajuns cu succes la server, a trecut autentificarea și a fost în coada de așteptare pentru a fi trimis la furnizorul de SMS-uri
  • FALSE – în toate celelalte cazuri

Aceasta încheie descrierea enunțului problemei! Și, în sfârșit, să trecem la partea distractivă - să ne dăm seama ce fel de fiară ciudată este acest SAPUN!

2 Ce este SAPUNUL?

În general, inițial nu am plănuit să scriu nimic despre ce este SOAP și am vrut să mă limitez la link-uri către site-ul w3.org cu specificațiile necesare, precum și link-uri către Wikipedia. Dar la final am decis să scriu o scurtă notă despre acest protocol.

Și îmi voi începe povestea cu faptul că acest protocol de schimb de date aparține unui subset de protocoale bazate pe așa-numita paradigmă RPC (Remote Procedure Call), al cărei antipod este REST (Representational State Transfer). Puteți citi mai multe despre acest lucru pe Wikipedia, link-urile către articole sunt chiar la sfârșitul subiectului. Din aceste articole trebuie să înțelegem următoarele: „Abordarea RPC vă permite să utilizați un număr mic de resurse de rețea cu un număr mare metode și protocol complex. Cu abordarea REST, numărul de metode și complexitatea protocolului sunt strict limitate, ceea ce înseamnă că numărul de resurse individuale poate fi mare.” Adică, în raport cu noi, asta înseamnă că în cazul abordării RPC pe site va exista întotdeauna o intrare (link) către serviciu și ce procedură să apelăm pentru a procesa datele primite pe care le transferăm împreună cu datele, în timp ce cu abordarea REST în site-ul nostru are multe intrări (link-uri), fiecare dintre acestea acceptând și procesând doar anumite date. Dacă cineva care citește știe cum să explice diferența dintre aceste abordări și mai simplu, nu uitați să scrieți în comentarii!

Următorul lucru pe care trebuie să-l știm despre SOAP este că acest protocol folosește același XML ca transport, ceea ce, pe de o parte, este foarte bun, deoarece imediat arsenalul nostru primește întreaga putere a unui teanc de tehnologii bazate pe limba dată markup, și anume XML-Schema - un limbaj de descriere a structurii unui document XML (mulțumesc Wikipedia!), care permite validarea automată a datelor primite de server de la clienți.

Și așa, acum știm că SOAP este un protocol folosit pentru a implementa apeluri de procedură de la distanță și folosește XML ca transport! Dacă citiți articolul de pe Wikipedia, puteți afla și de acolo că poate fi folosit pe deasupra oricărui protocol nivelul de aplicare, și nu doar asociat cu HTTP (din păcate, în acest subiect vom lua în considerare doar SOAP peste HTTP). Și știi ce îmi place cel mai mult la toate astea? Dacă nu există ghiciri, atunci voi da un indiciu - SAPUN!... Încă nu ghiciți?... Ești sigur că ai citit articolul de pe Wikipedia?... În general, nu te voi mai tortura. Prin urmare, voi merge direct la răspunsul: „SOAP (din engleză Simple Object Access Protocol - simplu protocol acces la obiecte; până la specificația 1.2)". Cel mai remarcabil lucru la această linie este scrisul cu caractere cursive! Nu știu ce concluzii ați tras din toate acestea, dar văd următoarele - deoarece acest protocol nu poate fi în niciun fel numit „simplu” (și se pare că chiar și w3 este de acord cu asta), atunci de la versiunea 1.2 a încetat cumva să fie decriptat ! Și a devenit cunoscut sub numele de SOAP, doar SOAP, punct.

Ei bine, vă rog să mă scuzați, am fost puțin deturnat. După cum am scris mai devreme, XML este folosit ca transport, iar pachetele care călătoresc între client și server se numesc plicuri SOAP. Dacă luați în considerare structura generală a plicului, vi se va părea foarte familiar, deoarece... seamănă cu structura unei pagini HTML. Are o secțiune principală - Învălui, care include secțiuni AntetŞi Corp, sau Vina. ÎN Corp datele sunt transmise și este o secțiune obligatorie a plicului, în timp ce Antet este opțională. ÎN Antet pot fi transmise autorizarea sau orice alte date care nu au legătură directă cu datele de intrare ale procedurilor serviciului web. Despre Vina nu este nimic special de spus, cu excepția faptului că vine la client de pe server în cazul oricăror erori.

Aici se termină povestea mea de recenzie despre protocolul SOAP (ne vom uita la plicurile în sine și la structura lor mai detaliat când clientul și serverul nostru vor învăța în sfârșit să le ruleze unul pe celălalt) și începe una nouă - despre companionul SOAP numit WSDL (Servicii Web Limbajul descrierii). Da, da, acesta este exact lucrul care îi sperie pe cei mai mulți dintre noi chiar și de a încerca să luăm și să implementăm API-ul nostru pe acest protocol. Ca rezultat, de obicei ne reinventăm roata cu JSON ca transport. Deci, ce este WSDL? WSDL este un limbaj pentru descrierea serviciilor web și accesarea acestora, pe baza Limbajul XML(c) Wikipedia. Dacă această definiție nu vă explică întregul sens sacru al acestei tehnologii, atunci voi încerca să o descriu cu propriile mele cuvinte!

WSDL este conceput pentru a permite clienților noștri să comunice în mod normal cu serverul. Pentru a face acest lucru, fișierul cu extensia „*.wsdl” descrie următoarele informații:

  • Ce spații de nume au fost folosite?
  • Ce scheme de date au fost folosite?
  • Ce tipuri de mesaje așteaptă serviciul web de la clienți?
  • Ce date aparțin căror proceduri de servicii web,
  • Ce proceduri conține serviciul web?
  • Cum ar trebui clientul să apeleze procedurile serviciului web,
  • La ce adresă trebuie trimise apelurile clienților?
După cum puteți vedea, acest dosarși există întregul serviciu web. Specificând adresa fișierului WSDL în client, vom ști totul despre orice serviciu web! Drept urmare, nu trebuie să știm absolut nimic despre locul în care se află serviciul web în sine. Tot ce trebuie să știți este locația fișierului său WSDL! Vom afla în curând că SOAP nu este la fel de înfricoșător precum spun proverbele rusești.

3 Introducere în XML-Schema

Acum știm multe despre ce este SOAP, ce este în el și avem o privire de ansamblu asupra stivei de tehnologie care îl înconjoară. Întrucât, în primul rând, SOAP este o metodă de interacțiune între un client și un server, iar limbajul de markup XML este folosit ca transport pentru acesta, în această secțiune vom înțelege puțin despre modul în care are loc validarea automată a datelor folosind scheme XML.

Scopul principal al diagramei este de a descrie structura datelor pe care urmează să le procesăm. Toate datele din schemele XML sunt împărțite în simplu(scalar) și complex(structuri) tipuri. Tipurile simple includ următoarele tipuri:

  • linia,
  • număr,
  • valoare booleană,
  • data.
Ceva foarte simplu care nu are extensii înăuntru. Antipodul lor este de tipuri complexe complexe. Cel mai simplu exemplu de tip complex care vine în minte tuturor sunt obiectele. De exemplu, o carte. Cartea constă din proprietăți: autor, Nume, preţ, numărul ISBN etc. Și aceste proprietăți, la rândul lor, pot fi fie tipuri simple, fie complexe. Și sarcina schemei XML este de a descrie acest lucru.

Vă sugerez să nu mergeți departe și să scrieți o schemă XML pentru mesajul nostru SMS! Mai jos este descrierea xml a mesajului SMS:

71239876543 Mesajul de testare 20-07-2013T12:00:00 12
Diagrama noastră de tip complex va arăta astfel:


Această intrare arată după cum urmează: Avem o variabilă " mesaj" tip " Mesaj„și există un tip complex numit „ Mesaj", care constă dintr-un set secvenţial de elemente" telefon" tip şir, « text" tip şir, « data" tip dateTime, « tip" tip zecimal. Aceste tipuri sunt simple și sunt deja definite în descrierea schemei. Felicitări! Tocmai am scris prima noastră schemă XML!

Cred că sensul elementelor " element" Și " complexType„Totul a devenit mai mult sau mai puțin clar pentru tine, așa că nu ne vom mai concentra asupra lor și hai să trecem direct la elementul compozitor” secvenţă" Când folosim elementul compozitor " secvenţă„Vă informăm că elementele incluse în acesta trebuie să fie întotdeauna amplasate în ordinea specificată în diagramă, iar toate sunt obligatorii. Dar nu dispera! Mai sunt două elemente de compoziție în schemele XML: " alegere" Și " toate" Compozitor" alegere" anunță că trebuie să existe unul dintre elementele enumerate în acesta, iar compozitorul " toate» – orice combinație a elementelor enumerate.

După cum vă amintiți, în prima secțiune a subiectului am convenit că de la unul la infinit mesajele SMS pot fi transmise într-un pachet. Prin urmare, îmi propun să înțelegem cum sunt declarate astfel de date în schema XML. Structura generală a pachetului ar putea arăta astfel:

71239876543 Mesajul de testare 1 20-07-2013T12:00:00 12 71239876543 Mesajul de testare N 20-07-2013T12:00:00 12
Diagrama pentru un astfel de tip complex va arăta astfel:


Primul bloc conține declarația familiară de tip complex „ Mesaj" Dacă ați observat, atunci în fiecare tip simplu inclus în " Mesaj", au fost adăugate noi atribute de clarificare" minApare" Și " maxApare" După cum ați putea ghici din nume, primul ( minApare) indică faptul că această secvență trebuie să conțină cel puțin un element de tip „ telefon», « text», « data" Și " tip", în timp ce următorul ( maxApare) atributul ne declară că există cel mult un astfel de element în secvența noastră. Ca rezultat, atunci când scriem propriile noastre scheme pentru orice date, ni se oferă cea mai largă alegere în ceea ce privește modul de configurare a acestora!

Al doilea bloc al diagramei declară elementul " listă de mesaje" tip " Listă de mesaje" Este clar că „ Listă de mesaje" este un tip complex care conține cel puțin un element " mesaj„, dar numărul maxim de astfel de elemente nu este limitat!

4 Scrieți WSDL

Vă amintiți că WSDL este serviciul nostru web? Sper să vă amintiți! Pe măsură ce îl scriem, micul nostru serviciu web va rula pe el. Prin urmare, vă sugerez să nu vă încurcați.

În general, pentru ca totul să funcționeze corect pentru noi, trebuie să transferăm fișierul WSDL cu tipul MIME corect către client. Pentru a face acest lucru, trebuie să configurați serverul dvs. web în consecință, și anume, setați tipul MIME pentru fișierele cu extensia „*.wsdl” la următoarea linie:

Aplicație/wsdl+xml
Dar, în practică, de obicei trimiteam antetul HTTP prin PHP " text/xml»:

Antet ("Content-Type: text/xml; charset=utf-8");
și totul a funcționat excelent!

Vreau să vă avertizez imediat că serviciul nostru web simplu va avea o descriere destul de impresionantă, așa că nu vă alarmați, pentru că... Majoritatea textului este apă obligatorie și, după ce l-a scris o singură dată, îl poți copia constant de la un serviciu web la altul!

Deoarece WSDL este XML, trebuie să scrieți despre asta direct în prima linie. Elementul rădăcină al fișierului ar trebui să fie întotdeauna numit „ definiții»:


De obicei, WSDL constă din 4-5 blocuri principale. Primul bloc este definiția unui serviciu web sau, cu alte cuvinte, punctul de intrare.


Aici scrie că avem un serviciu numit - „ Serviciu SMS" În principiu, toate denumirile din fișierul WSDL pot fi schimbate de dvs. în orice doriți, pentru că nu joacă absolut niciun rol.

După aceasta vă anunțăm că în serviciul nostru web " Serviciu SMS" există un punct de intrare ("port") numit " SMSServicePort" La acest punct de intrare vor fi trimise toate cererile de la clienți către server. Și indicați în elementul „ adresa» link la fișierul de gestionare care va accepta cereri.

Odată ce am definit serviciul web și am specificat punctul de intrare pentru acesta, trebuie să le legăm procedurile acceptate:


Pentru a face acest lucru, listează ce operațiuni și sub ce formă vor fi numite. Aceste. pentru port" SMSServicePort" o legare este definită sub numele " SMSServiceBinding", care are un tip de apel " rpc„și HTTP este folosit ca protocol de transmisie. Astfel, am indicat aici că vom efectua un apel RPC prin HTTP. După aceasta, descriem ce proceduri ( operare) sunt acceptate în serviciul web. Vom sprijini o singură procedură – „ trimite SMS" Prin această procedură minunatele noastre mesaje vor fi trimise către server! După ce procedura a fost declarată, este necesar să se indice sub ce formă vor fi transmise datele. În acest caz, este indicat că vor fi folosite plicuri SOAP standard.

După aceea, trebuie să legăm procedura de mesaje:


Pentru a face acest lucru, precizăm că legarea noastră este de tip " SMSServicePortType"și în elementul" portType„cu denumirea de același tip, indicăm legarea procedurilor de mesaje. Aşa, mesaj primit(de la client la server) se va numi „ trimiteSmsRequest", și de ieșire (de la server la client) " trimiteSmsResponse" Ca toate numele din WSDL, numele mesajelor de intrare și de ieșire sunt arbitrare.

Acum trebuie să descriem mesajele în sine, de ex. de intrare și de ieșire:


Pentru a face acest lucru adăugăm elementele " mesaj"cu nume" trimiteSmsRequest" Și " trimiteSmsResponse„, respectiv. În ele indicăm că intrarea ar trebui să fie un plic a cărui structură corespunde tipului de date " Cerere" După care se returnează de la server un plic care conține tipul de date - „ Răspuns».

Acum trebuie să facem doar puțin - adăugați o descriere a acestor tipuri în fișierul nostru WSDL! Și cum credeți că WSDL descrie datele de intrare și de ieșire? Cred că ai înțeles deja totul cu mult timp în urmă și ți-ai spus că folosind scheme XML! Și vei avea perfectă dreptate!


Ne poți felicita! Primul nostru WSDL a fost scris! Și suntem cu un pas mai aproape de a ne atinge obiectivul.
În continuare, ne vom uita la ce ne oferă PHP pentru dezvoltarea propriilor aplicații distribuite.

5 Primul nostru server SOAP

Mai devreme am scris că pentru a crea un server SOAP în PHP vom folosi clasa încorporată SoapServer. Pentru ca totul acțiuni ulterioare s-a întâmplat în același mod ca și al meu, va trebui să vă modificați puțin PHP. Pentru a fi și mai precis, trebuie să vă asigurați că aveți instalată extensia „php-soap”. Cel mai bine este să citiți cum să îl instalați pe serverul dvs. web de pe site-ul oficial PHP (vezi lista de referințe).

După ce totul a fost instalat și configurat, va trebui să creăm un fișier în folderul rădăcină al găzduirii dvs. „ smsservice.php» cu următorul conținut:

setClass("SoapSmsGateWay"); //Porniți serverul $server->handle();
Sper că nu este nevoie să explic ce este deasupra liniei cu funcția „ini_set”. Deoarece acolo se determină ce anteturi HTTP vom trimite de la server către client și se configurează mediul. În conformitate cu „ini_set”, dezactivăm memorarea în cache a fișierului WSDL, astfel încât modificările noastre să aibă efect imediat asupra clientului.

Acum ajungem la server! După cum puteți vedea, întregul server SOAP are doar trei linii! Pe prima linie, creăm o nouă instanță a obiectului SoapServer și transmitem adresa descrierii noastre WSDL a serviciului web constructorului său. Acum știm că va fi localizat în rădăcina găzduirii într-un fișier cu numele auto-explicativ „ smsservice.wsdl.php" În a doua linie, îi spunem serverului SOAP care clasă trebuie extrasă pentru a procesa plicul primit de la client și a returna plicul cu răspunsul. După cum probabil ați ghicit, singura noastră metodă va fi descrisă în această clasă trimite SMS. Pe a treia linie pornim serverul! Gata, serverul nostru este gata! Cu care ne felicit pe toti!

Acum trebuie să creăm fișierul WSDL. Pentru a face acest lucru, puteți fie să îi copiați pur și simplu conținutul din secțiunea anterioară, fie să vă luați libertăți și să îl „șabloniți” puțin:

"; ?> /" 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" />
În această etapă, ar trebui să fim complet mulțumiți de serverul rezultat, deoarece Putem înregistra plicurile care vin la el și apoi analizăm cu calm datele primite. Pentru a primi ceva pe server, avem nevoie de un client. Deci să trecem la asta!

6 client SOAP pe drum

În primul rând, trebuie să creăm un fișier în care vom scrie clientul. Ca de obicei, îl vom crea în rădăcina gazdei și îl vom numi " client.php", iar în interior vom scrie următoarele:

MessageList = new MessageList(); $req->messageList->message = mesaj nou(); $req->messageList->message->phone = "79871234567"; $req->messageList->message->text = "Testează mesajul 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($client->sendSms($req));
Să ne descriem obiectele. Când am scris WSDL, acesta a descris trei entități pentru plicul primit pe server: Cerere, Listă de mesajeŞi Mesaj. În consecință, clasele Cerere, Listă de mesajeŞi Mesaj sunt reflectări ale acestor entități în scriptul nostru PHP.

Odată ce am definit obiectele, trebuie să creăm un obiect ( $req), pe care îl vom trimite către server. După care vin cele mai prețuite două replici pentru noi! Clientul nostru SOAP! Credeți sau nu, acest lucru este suficient pentru ca serverul nostru să înceapă să primească mesaje de la client, precum și pentru ca serverul nostru să le primească și să le proceseze cu succes! În primul dintre ele, creăm o instanță a clasei SoapClient și transmitem adresa locației fișierului WSDL constructorului acestuia, iar în parametri indicăm în mod explicit că vom lucra folosind protocolul SOAP versiunea 1.2. Pe linia următoare numim metoda trimite SMS obiect $clientși afișați imediat rezultatul în browser.
Hai să-l rulăm și să vedem ce avem în sfârșit!

Următorul obiect mi-a fost returnat de pe server:

Object(stdClass) public "status" => boolean adevărat
Și asta este grozav, pentru că... Acum știm sigur că serverul nostru funcționează și nu numai că funcționează, dar poate returna și câteva valori clientului!

Acum să ne uităm la jurnalul pe care îl păstrăm cu prudență pe partea serverului! În prima parte vedem datele brute care au ajuns la server:

79871234567 Mesajul de testare 1 2013-07-21T15:00:00.26 15
Acesta este plicul. Acum știi cum arată! Dar este puțin probabil să fim interesați să ne uităm la asta tot timpul, așa că haideți să deserializăm obiectul din fișierul jurnal și să vedem dacă totul este bine:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => șir "79871234567" (lungime=11) public "text" => șir "Test mesaj 1 " (lungime=37) public "date" => șir "2013-07-21T15:00:00.26" (lungime=22) public "tip" => șir "15" (lungime=2)
După cum puteți vedea, obiectul a fost deserializat corect, pentru care vreau să ne felicit pe toți! Ceva mai interesant ne așteaptă în continuare! Și anume, vom trimite clientul către server nu doar un mesaj SMS, ci un pachet întreg (mai precis, trei)!

7 Trimiterea obiectelor complexe

Să ne gândim cum putem transfera o grămadă de mesaje pe server într-un singur pachet? Probabil cel mai mult într-un mod simplu va exista o organizare matrice în interiorul elementului messageList! Să facem asta:

// creăm un obiect de trimis la server $req = new Request(); $req->messageList = new MessageList(); $msg1 = mesaj nou(); $msg1->telefon = "79871234567"; $msg1->text = "Test mesajul 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->tip = 15; $msg2 = mesaj nou(); $msg2->telefon = "79871234567"; $msg2->text = "Test mesajul 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->tip = 16; $msg3 = mesaj nou(); $msg3->telefon = "79871234567"; $msg3->text = "Test mesajul 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->tip = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $msg3;
Jurnalele noastre indică faptul că următorul pachet a fost primit de la client:

79871234567 Mesajul de testare 1 2013-07-21T15:00:00.26 15 79871234567 Mesajul de testare 2 2014-08-22T16:01:10 16 79871234567 Mesajul de testare 3 2014-08-22T16:01:10 17
Ce prostie, zici? Și vei avea dreptate într-un fel, pentru că... De îndată ce am aflat că un obiect a părăsit clientul, acesta a ajuns la serverul nostru în absolut aceeași formă sub forma unui plic. Adevărat, mesajele SMS nu erau serializate în XML în modul în care aveam nevoie - trebuiau să fie împachetate în elemente mesaj, nu in Struct. Acum să vedem în ce formă un astfel de obiect vine la metodă trimite SMS:

Object(stdClass) public "messageList" => obiect(stdClass) public "message" => object(stdClass) public "Struct" => matrice (dimensiune=3) 0 => obiect(stdClass) public "telefon" => șir „79871234567” (lungime=11) public „text” => șir „Test mesajul 1” (lungime=37) public „date” => șir „2013-07-21T15:00:00.26” (lungime=22) public „ tip" => șir "15" (lungime=2) 1 => obiect(stdClass) public "telefon" => șir "79871234567" (lungime=11) public "text" => șir "Mesaj de testare 2" (lungime= 37) public „date” => șir „2014-08-22T16:01:10” (lungime=19) public „tip” => șir „16” (lungime=2) 2 => obiect(stdClass) public „telefon " => șir "79871234567" (lungime=11) public "text" => șir "Test mesaj 3" (lungime=37) public "date" => șir "2014-08-22T16:01:10" (lungime= 19) public „type” => șir „17” (lungime=2)
Ce ne oferă această cunoaștere? Doar că calea pe care am ales-o nu este corectă și nu am primit un răspuns la întrebarea - „Cum putem ajunge pe server structura corecta date? Dar vă sugerez să nu disperați și să încercați să convertiți matricea noastră la tipul obiect:

$req->messageList->message = (obiect)$req->messageList->mesaj;
În acest caz, vom primi un alt plic:

79871234567 Mesajul de testare 1 2013-07-21T15:00:00.26 15 79871234567 Mesajul de testare 2 2014-08-22T16:01:10 16 79871234567 Mesajul de testare 3 2014-08-22T16:01:10 17
A intrat în metodă trimite SMS obiectul are următoarea structură:

Object(stdClass) public "messageList" => obiect(stdClass) public "message" => object(stdClass) public "BOGUS" => matrice (dimensiune=3) 0 => obiect(stdClass) public "telefon" => șir „79871234567” (lungime=11) public „text” => șir „Test mesajul 1” (lungime=37) public „date” => șir „2013-07-21T15:00:00.26” (lungime=22) public „ tip" => șir "15" (lungime=2) 1 => obiect(stdClass) public "telefon" => șir "79871234567" (lungime=11) public "text" => șir "Mesaj de testare 2" (lungime= 37) public „date” => șir „2014-08-22T16:01:10” (lungime=19) public „tip” => șir „16” (lungime=2) 2 => obiect(stdClass) public „telefon " => șir "79871234567" (lungime=11) public "text" => șir "Test mesaj 3" (lungime=37) public "date" => șir "2014-08-22T16:01:10" (lungime= 19) public „type” => șir „17” (lungime=2)
În ceea ce mă privește, „suma nu se schimbă din schimbarea locurilor termenilor” (c). Ce FALS, Ce Struct– încă nu ne-am atins scopul! Și pentru a realiza acest lucru, trebuie să ne asigurăm că în locul acestor nume de neînțeles este afișat cel nativ. mesaj. Dar autorul nu știe încă cum să realizeze acest lucru. Prin urmare, singurul lucru pe care îl putem face este să scăpăm de recipientul suplimentar. Cu alte cuvinte, acum ne vom asigura că în loc de mesaj devenit FALS! Pentru a face acest lucru, schimbați obiectul după cum urmează:

// creăm un obiect de trimis la server $req = new Request(); $msg1 = mesaj nou(); $msg1->telefon = "79871234567"; $msg1->text = "Test mesajul 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->tip = 15; $msg2 = mesaj nou(); $msg2->telefon = "79871234567"; $msg2->text = "Test mesajul 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->tip = 16; $msg3 = mesaj nou(); $msg3->telefon = "79871234567"; $msg3->text = "Test mesajul 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->tip = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (obiect)$req->messageList;
Ce se întâmplă dacă avem noroc și numele corect iese din diagramă? Pentru a face acest lucru, să ne uităm la plicul care a sosit:

79871234567 Mesajul de testare 1 2013-07-21T15:00:00.26 15 79871234567 Mesajul de testare 2 2014-08-22T16:01:10 16 79871234567 Mesajul de testare 3 2014-08-22T16:01:10 17
Da, nu s-a întâmplat un miracol! FALS– nu vom câștiga! A venit la trimite SMS obiectul în acest caz va arăta astfel:

Object(stdClass) public "messageList" => object(stdClass) public "BOGUS" => array (size=3) 0 => object(stdClass) public "phone" => șir "79871234567" (lungime=11) public " text" => șir "Test mesajul 1" (lungime=37) public "date" => șir "2013-07-21T15:00:00.26" (lungime=22) public "type" => șir "15" (lungime =2) 1 => obiect(stdClass) public "telefon" => șir "79871234567" (lungime=11) public "text" => șir "Test mesaj 2" (lungime=37) public "date" => șir " 2014-08-22T16:01:10" (lungime=19) public "type" => șir "16" (lungime=2) 2 => obiect(stdClass) public "telefon" => șir "79871234567" (lungime= 11) public "text" => șir "Test mesajul 3" (lungime=37) public "date" => șir "2014-08-22T16:01:10" (lungime=19) public "type" => șir " 17" (lungime=2)
După cum se spune – „Aproape”! Pe această notă (puțin tristă), îmi propun să încheiem treptat lucrurile și să tragem niște concluzii pentru noi înșine.

8 Concluzie

In sfarsit am ajuns aici! Să ne dăm seama ce poți face acum:
  • puteți scrie fișierul WSDL necesar serviciului dvs. web;
  • puteți scrie cu ușurință propriul client care poate comunica cu serverul prin SOAP;
  • poți să-l scrii pe al tău propriul server comunicarea cu lumea exterioară prin SOAP;
  • puteți trimite matrice de același tip de obiecte către server de la clientul dvs. (cu unele restricții).
Am făcut și câteva descoperiri în timpul micii noastre cercetări:
  • clasa nativă SoapClient nu serializează corect structurile de date de același tip în XML;
  • atunci când serializează o matrice în XML, acesta creează un element suplimentar numit Struct;
  • atunci când serializează un obiect în XML, acesta creează un element suplimentar numit FALS;
  • FALS răul mai mic Cum Struct datorită faptului că plicul este mai compact (nu se adaugă spații de nume suplimentare la antetul XML al plicului);
  • Din păcate, clasa SoapServer nu validează automat datele plicului cu schema noastră XML (poate că nici alte servere nu fac acest lucru).

În general, astăzi există protocoale standard de schimb de date XML:

  • XML-RPC– treci pachetul și indică ce metodă de pe server vrei să apelezi.
  • ODIHNĂ- există câteva obiecte pe server. Fiecare obiect este caracterizat de un fel de identificator. Fiecare element are propria sa adresă URL. Puteți face următoarele cu orice element: inserați, ștergeți, actualizați, selectați. Pur și simplu trimiteți cererea dorită către server (de exemplu, introduceți un astfel de element). Schimbul client-server se bazează fie pe JSON, fie pe XML.

SOAP (arhitectura orientată pe servicii, un set de servicii slab cuplate care interacționează între ele) se bazează pe RPC. Principalul avantaj al RPC este numărul mic de resurse de rețea (puncte de intrare) și numeroasele metode implicate. În ciuda acestui avantaj, RPC este un protocol învechit care are o serie de dezavantaje:

  • Valabilitatea unui mesaj XML-RPC nu poate fi verificată. Vechiul protocol a fost creat înainte ca schemele (metode de validare a datelor) să fie standardizate în XML. Aceste. Serverul acceptă cereri, trebuie să se asigure că solicitările sunt pentru el și că datele sunt consecvente. În XML-RPC, tipurile de date sunt declarate pentru aceasta, dar aceasta este o verificare a tipului de date, iar consistența datelor nu este verificată (că ați primit o structură cu toți parametrii necesari).
  • Nu puteți crea mesaje combinate.
  • Nu puteți folosi spațiul și timpul (a apărut după crearea RPC).
  • Nu puteți extinde mesajul, de exemplu. adăugați informații suplimentare.

Toate aceste neajunsuri au fost rezolvate în XML Schema. Acesta este un standard industrial Descrieri XML document. Aceste. este o modalitate de a modela date arbitrare. O schemă XML poate descrie un model (relațiile dintre elemente și atribute și structura acestora), tipuri de date (caracterizează tipuri de date) și un dicționar (nume de elemente și atribute).

Pe baza tuturor deficiențelor XML-RPC, a fost creat protocolul SOAP.

SĂPUN(Simle Object Access Protocol) - protocol de acces la un obiect (la punctul de intrare). Astăzi este principalul standard industrial pentru construirea de aplicații distribuite.

Reprezintă extensii ale limbajului XML-RPC. Aceste. este construit pe principiul: 1 punct de intrare și orice metode. Protocolul în sine în ceea ce privește transportul (cum se transferă datele) oferă gamă largă: SMTP, FTP, HTTP, MSMQ.

SOAP stă la baza implementării serviciilor web XML (servicii web XML). Dezavantajul SOAP este că este greu de învățat.

SOAP se bazează pe schimbul de mesaje între un client și un server (sincron și asincron). Fiecare mesaj conține informații despre date (ce date sunt transmise și primite). SOAP descrie în prealabil întreaga structură a unui mesaj folosind scheme XML: ce ar trebui să fie în mesaj, cum va fi transmis. Acest lucru face posibil, fără a cunoaște serverul, să înțelegem ce se întâmplă acolo și îi permite serverului să verifice dacă acest mesaj este potrivit.

Schema XML

Scopul unei scheme este de a descrie structura datelor, de ex. ce avem. Toate datele sunt împărțite în tipuri simple și complexe (scalare și structuri). Un tip simplu (șir, număr, boolean, dată) nu va conține niciodată nimic în interior. Și o structură (obiect) poate conține proprietăți.

Operațiuni SOAP de bază

  • Nu doar un simplu schimb de informații client-server. Dar de asemenea recunoaștere automată server și căutați acest server, de ex. clientul poate nici măcar să nu știe nimic despre server. Aceste. clientul caută mai întâi serverul, găsește servicii potrivite, înțelege ce metode există, ce are serverul și îl numește.
  • Serverul își publică informațiile (locația, ce metode acceptă) astfel încât clientul să găsească acest server. Publicarea are loc în directorul UDDI.

Structura mesajului SOAP:

  • Plic SOAP - acesta include întregul mesaj. Constă dintr-un antet și un corp.
  • Antet SOAP (antet) - informații suplimentare (autorizare, de exemplu).
  • SOAP Corp (corp) - mesajul în sine.
  • SOAP Fault (eroare) este o metodă de transmitere a unei erori de la server către client.

WSDL

WSDL(Web Services Description Language) - limbaj pentru descrierea serviciilor web. Folosit în SOAP. Acesta este un fel de document care descrie totul: ce spații de nume au fost folosite, ce scheme de date au fost folosite, ce tipuri de mesaje așteaptă serverul de la client, ce plicuri aparțin cărei metode, ce metode există, la ce adresă să trimită etc. . De fapt, WSDL este un serviciu web. Este suficient ca clientul să studieze conținutul acestui document, el știe deja totul despre server.

Orice server trebuie să publice WSDL.

WSDL este format din blocuri:

  • Definiția serviciului în sine, de ex. punctul de intrare, portul este indicat.
  • Formatul metodelor. Punctul de intrare este legat de operațiuni, de exemplu. ce metode suporta? Sunt indicate tipul apelului și metoda de transmitere. În interiorul fiecărei metode există o explicație a formei în care sunt transmise datele – sub formă de SOAP.
  • Metode de legare la un mesaj.
  • Descrierea mesajelor în sine.

După cum sa discutat în capitolul anterior, serviciile Web comunică cu clienții și între ele prin trimiterea de mesaje în XML. Etichetele acestei implementări XML, regulile de formatare a documentului XML și ordinea în care sunt schimbate documentele sunt definite de protocolul SOAP. Protocolul SOAP a fost creat în 1998 de o echipă de dezvoltatori condusă de Dave Winer, care a lucrat la Microsoft Corporation și Userland. Numele protocolului - „Simple Object Access Protocol” - reflectă scopul său inițial - de a accesa metodele obiectelor de la distanță. Scopul protocolului s-a schimbat; acum este un protocol pentru orice interacțiune între serviciile Web și componentele aplicațiilor distribuite slab cuplate. Nu mai este destul de simplu și nu spune nimic despre obiecte. Mulți dezvoltatori sugerează să-l numească „Protocol de arhitectură orientată pe servicii”, lăsând abrevierea anterioară. Pentru a opri aceste încercări, specificația SOAP 1.2 afirmă că cuvântul „SOAP” nu va mai fi scris în niciun fel.

La sfârșitul anului 1999, dezvoltarea protocolului a fost transferată consorțiului W3C (http:// www.w3.org/).

În mai 2000, consorțiul și-a lansat versiunea SOAP 1.1. Un mesaj scris folosind protocolul SOAP este formatat ca un document XML care utilizează în mod activ spațiile de nume. Numele elementelor XML SOAP 1.1 se referă la identificatorul de spațiu de nume http://schemas.xmlsoap.org/soap/envelope/.

A doua versiune a SOAP 1.2 a fost lansată în 2001, spațiul său de nume la acel moment se numea http://www.w3.org/2001/06/soap-envelope.

Rețineți că este identificatorul spațiului de nume, nu numărul 1.1 sau 1.2, care determină versiunea SOAP. Serverul nu va lua în considerare mesajul SOAP și va returna un mesaj de eroare dacă observă

nepotrivirea spațiului de nume.

În timp ce scriu asta, SOAP 1.1 rămâne în funcțiune. Versiunea 1.2 nu poate părăsi etapa pregătitoare, dar este deja folosită, de exemplu, în SOAP::Lite, Apache SOAP 2.3, Apache Axis. Prin urmare, în acest capitol voi schița versiunea 1.2, notând diferențele acesteia față de versiunea 1.1.

Specificația SOAP de lucru este întotdeauna stocată la http://www.w3.org/TR/SOAP/. Documentele aflate la această adresă sunt înlocuite cu altele noi atunci când versiunea de lucru este înlocuită.

Schița SOAP este actualizată continuu, iar identificatorul spațiului de nume se modifică. Cea mai nouă opțiune Versiunea nefinalizată la momentul scrierii se afla la http://www.w3.org/TR/soapl2-partl/, iar spațiul de nume folosit se numea http://www.w3.org/2002/06/soap -plic. Rețineți că specificația SOAP 12 constă din două părți: partea 1 și partea 2. A doua parte a specificației - aplicația - conține reguli pentru înregistrarea tipurilor de date complexe. Specificația are încă o parte, partO - exemple de mesaje compilate conform regulilor SOAP 1.2.

Structura mesajului SOAP

Specificația definește un mesaj SOAP ca un document XML care nu conține o declarație de tip de document sau instrucțiuni de procesare. Elementul rădăcină al acestui document XML este numit . Un element poate avea atribute care definesc spațiile de nume,

și alte atribute prevăzute cu prefixe. Elementul rădăcină conține un element opțional care conține antetul mesajului și un element obligatoriu , în care este înregistrat conținutul mesajului. Versiunea 1.1 permisă după corp pentru a scrie elemente arbitrare, numele lor trebuia să fie prefixat. Versiunea 1.2 interzice scrierea a ceva după element . Pe scurt, structura generală a unui mesaj SOAP este:

xmlns:env="http://www.w3.org/2002/06/soap-envelope">

< ! - Блоки заголовка ->

Element

, dacă se află în mesaj, este scris mai întâi în corpul elementului . În plus față de atributele xmlns, acesta poate conține un atribut actor, care indică adresa URI a serverului SOAP specific căruia îi este destinat mesajul.

Cert este că un mesaj SOAP poate trece prin mai multe servere SOAP sau prin mai multe aplicații de pe același server. Aceste aplicații preprocesează blocurile de antet de mesaje și le transmit unele altora. Toate aceste servere și/sau aplicații sunt numite noduri SOAP. Specificația SOAP nu definește reguli pentru transmiterea unui mesaj printr-un lanț de servere. În acest scop, sunt dezvoltate și alte protocoale, de exemplu, Microsoft WS-Routing.

Atributul actor specifică nodul SOAP țintă - cel care se află la capătul lanțului și va procesa întregul antet. Sens

Atributul actor indică faptul că antetul va fi procesat de primul server care îl primește. Atributul actor poate apărea în blocuri de antet separate, indicând nodul care se ocupă de acest bloc. După procesare, blocul este eliminat din mesajul SOAP.

În versiunea 1.2, atributul actor este înlocuit cu atributul rol deoarece în această versiune de SOAP, fiecare nod joacă unul sau mai multe roluri. Specificația definește în prezent trei roluri de noduri SOAP.

Rolul http://^^.w3.org/2002/06/soap-envelope/role/ultimateReceiver este jucat de nodul final, țintă, care va procesa antetul.

Rolul http://www.w3.org/2002/06/soap-envelope/role/next este jucat de nodul intermediar sau țintă. Un astfel de nod poate juca alte roluri suplimentare.

Rolul http://www.w3.org/2002/06/soap-envelope/role/none nu ar trebui să fie jucat de niciun nod SOAP.

Aplicațiile distribuite, în funcție de nevoile lor, pot adăuga alte roluri acestor roluri, de exemplu, introducerea unui server intermediar care verifică semnătură digitalăși definiți acest rol pentru el cu un șir URI.

Valoarea atributului rol poate fi orice șir URI care indică rolul nodului căruia îi este destinat acest bloc de antet. Valoarea implicită pentru acest atribut este valoarea goală, adică doar o pereche de ghilimele sau șirul URI http://\vw\v.w3.org/2002/06/soap-envelope/rale/ultimateReceiver.

Valoarea atributului rol indică faptul că blocul trebuie procesat de un nod care joacă rolul specificat de același șir.

Un alt atribut al elementului

, numit urnstUnderstand, ia valorile o sau 1. Valoarea sa implicită este o. Dacă atributul mustunderstand este egal cu 1, atunci nodul SOAP, atunci când procesează elementul, trebuie să țină cont de sintaxa acestuia definită în schema documentului sau să nu proceseze deloc mesajul. Acest lucru crește acuratețea procesării mesajelor.

În versiunea SOAP 1.2, în loc de numărul o, trebuie să scrieți cuvântul false, iar în loc de numărul 1, scrieți cuvântul adevărat.

În corpul antetului

Puteți imbrica elemente arbitrare, numite anterior intrări de antet. În versiunea 1.2 acestea se numesc blocuri de antet. Numele lor sunt în mod necesar marcate cu prefixe. Blocurile de antet pot conține atributele rol sau actor și trebuie să înțeleg. Acțiunea lor se va aplica numai acestui bloc. Acest lucru permite ca blocurile de antet individuale să fie procesate de nodurile SOAP intermediare, cele al căror rol se potrivește cu rolul specificat de atributul rol. Lista 3.1 prezintă un exemplu de astfel de bloc.

Lista 3.1. Antet cu un singur bloc

xmlns:t="http://some.com/transaction" env:role=

„http://www.w3.org/2002/06/soap-envelope/role/ultimateReceiver” env:mustUnderstand="1">

Elementele imbricate în blocurile antet nu mai sunt numite blocuri. Ele nu pot conține rolul, actorul și atributele trebuie să înțeleagă.

Element trebuie scris imediat după element

, dacă este în mesaj sau mai întâi în mesajul SOAP dacă antetul lipsește. Pentru a element Puteți imbrica elemente arbitrare; specificația nu definește în niciun fel structura acestora. Cu toate acestea, este definit un element care conține un mesaj de eroare.

Mesaj de eroare

Dacă un server SOAP, în timp ce procesează un mesaj SOAP primit de acesta, observă o eroare, acesta va opri procesarea și va trimite clientului un mesaj SOAP, în corpul căruia va scrie un element cu un mesaj de eroare.

În mesajul scris în corpul unui element SOAP 1.1,

Există patru părți descrise de următoarele subelemente.

Cod de eroare - un mesaj care indică tipul de eroare. Este destinat unui program care se ocupă de erori.

Descrierea erorii - o descriere verbală a tipului de eroare destinată unei persoane.

Unde a fost găsită eroarea - URI-ul serverului care a observat eroarea. Util atunci când un mesaj trece printr-un lanț de noduri SOAP pentru a clarifica natura erorii. Nodurile SOAP intermediare sunt necesare pentru a înregistra acest element;

Detalii despre eroare - descrie erorile întâlnite în organism mesaj, dar nu în titlu. Dacă nu sunt găsite erori în timpul procesării corpului, atunci acest element lipsește.

De exemplu:

xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">

env:Must Understand SOAP trebuie să înțeleagă eroarea

Versiunea SOAP 1.2 a schimbat conținutul elementului Așa cum este descris în

namespace http://www.w3.org/2002/06/soap-envelope, include două elemente obligatorii și trei elemente opționale.

Elemente necesare.

Cod de eroare . Conține un subelement necesar<:value>cu un cod de eroare și un subelement opțional , conținând, din nou, elementul cu codul de eroare de clarificare și element , iar apoi totul se repetă recursiv.

Motivul erorii . Conține un atribut xml opțional: lang, care indică limba mesajului (vezi capitolul D) și un număr arbitrar de elemente imbricate care descriu eroarea.

Elemente optionale.

? - URI-ul nodului SOAP intermediar care a observat eroarea.

? - rolul nodului SOAP care a observat eroarea.

? - descrierea erorii observate la procesarea corpului mesaj, dar nu titlul.

Listarea 3.2 arată un mesaj de eroare care a apărut la încercarea de a executa o procedură. Eroarea este că numele argumentelor procedurii sunt scrise incorect în mesajul SOAP și procedura nu le poate înțelege.

Lista 3.2. Mesaj de eroare

xmlns:env="http://www.w3.org/2002/06/soap-envelope" xmlns:rpc=’http://www.w3.org/2002/06/soap-rpc’>

env:Expeditor

rpc:BadArgumentsc/env:Value>

Ptocessing ETror

xmlns:e="http://www.example.org/faults"> #me nu se potrivește 999

Tipuri de erori

Lista codurilor de eroare este în continuă schimbare și extindere. Versiunea 1.1 definește patru tipuri de erori.

VersionMismatch - spațiul de nume este nerecunoscut. Poate fi depășit sau numele său poate fi scris greșit.

MustUnderstand - Un bloc de antet marcat cu un atribut mustUnderstand cu o valoare de 1 nu este conform cu sintaxa sa definită în schema documentului.

Client - documentul XML care conține mesajul este malformat și din acest motiv serverul nu îl poate procesa. Clientul ar trebui să schimbe mesajul.

Server - serverul nu poate procesa mesajul înregistrat corect din motive interne.

Versiunea 1.2 definește cinci tipuri de erori.

VersionMismatch - spațiul de nume este nerecunoscut. Poate fi învechit sau numele său poate fi scris greșit sau poate exista un nume de element XML în mesaj care nu este definit în acel spațiu de nume. Serverul scrie elementul în antetul răspunsului , enumerând elemente imbricate nume corecte spații de nume înțelese de server. Răspunsul serverului este prezentat în Lista 3.3.

MustUnderstand - Un bloc de antet marcat cu atributul mustunderstand setat la true nu este conform cu sintaxa sa definită în schema documentului. Serverul scrie următoarele elemente în antetul răspunsului: , al cărui atribut qname conține numele blocului incorect. Lista 3.4 conține un exemplu de răspuns pe care serverul l-ar da dacă antetul din Lista 3.1 ar fi scris greșit.

DataEncodingUnknown - mesajul conținea date de neînțeles, poate a fost scris într-o codificare necunoscută.

Sender - documentul XML care conține mesajul este malformat și din acest motiv serverul nu îl poate procesa. Clientul ar trebui să schimbe mesajul.

Destinator - serverul nu poate procesa mesajul înregistrat corect din motive interne, de exemplu, lipsește analizatorul XML necesar.

Serverul poate adăuga unele dintre propriile tipuri la aceste tipuri de erori. De obicei

ei detaliază tipuri standard, iar mesajele despre ele apar în elemente , așa cum se arată mai sus în Lista 3.2.

? Lista 3.3. Răspunsul serverului cu un mesaj de eroare precum VersionMismatch

xmlns:env="http://www.w3.org/2002/06/soap-envelope">

xmlns:upg="http://www.w3.org/2002/06/soap-upgrade">

xmlns:nsl="http://www.w3.org/2002/06/soap-envelope"/>

xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"/>

env:VersionMismatch

Versiune nepotrivită

ListongZ.4. Răspunsul serverului cu un mesaj de eroare precum MustUnderstand

xmlns:t=’http://some.com/transaction’ />

env:Must Understand

Unul sau mai multe antete obligatorii nu sunt înțelese

Literatură:

Khabibullin I. Sh. Dezvoltarea serviciilor web folosind Java. - Sankt Petersburg: BHV-Petersburg, 2003. - 400 p.: ill.

SĂPUN-un protocol text care folosește XML pentru a schimba mesaje structurate într-un mediu de calcul distribuit. SOAP a fost inițial destinat în primul rând să implementeze apeluri de procedură la distanță (RPC), iar numele era un acronim: Simple Object Access Protocol. Protocolul este acum folosit pentru a schimba mesaje arbitrare în format XML, și nu doar pentru a apela proceduri. Specificație oficială ultima versiune 1.2 al protocolului nu descifrează în niciun fel numele SOAP. SOAP este o extensie a protocolului XML-RPC. SOAP poate fi utilizat cu orice protocol de nivel de aplicație: SMTP, FTP, HTTP etc. Cu toate acestea, interacțiunea sa cu fiecare dintre aceste protocoale are propriile caracteristici care trebuie definite separat. Cel mai adesea, SOAP este folosit prin HTTP. SOAP este unul dintre standardele pe care se bazează tehnologiile serviciilor web. Comunicarea între serviciile web și clienții acestora se realizează prin mesaje în format XML. SOAP (Simple Object Access Protocol) este un protocol de mesaje pentru selectarea serviciilor web. Putem spune că formatul SOAP este ideal pentru tehnologia RPC (Remote Procedure Call), întrucât mesajul SOAP conține parametri transmisi de client sau o valoare returnată transmisă de serviciu.

Avantajele utilizării formatului SOAP:

· Tipuri de date mai flexibile.

· Suport pentru anteturi și extensii:

Defecte:

· Folosirea SOAP pentru transmiterea mesajelor crește volumul acestora și reduce viteza de procesare. În sistemele în care viteza este importantă, este mai obișnuit să se trimită documente XML direct prin HTTP, unde parametrii de solicitare sunt trecuți ca parametri HTTP obișnuiți.

· Deși SOAP este un standard, diverse programe generează adesea mesaje într-un format incompatibil. De exemplu, o solicitare generată de un client AXIS nu va fi înțeleasă de serverul WebLogic.

Concepte de bază ale protocolului: Partea care trimite mesajul SOAP se numește expeditor SOAP, iar partea care primește se numește receptor SOAP. Calea pe care o ia un mesaj SOAP de la expeditorul inițial la destinatarul final se numește ruta mesajului. Ruta mesajului conține expeditorul inițial, destinatarul final și 0 sau mai mulți intermediari SOAP. Obiectele care procesează mesajele conform regulilor protocoalelor SOAP specifice sunt numite noduri SOAP. Se numește unitatea elementară de informații care participă la schimbul dintre nodurile SOAP mesaj SOAP este un document XML cu un înveliș SOAP în jurul elementului rădăcină.