Serviciu web SOAP folosind Spring-WS. Descrierea Serviciilor Web în limbajul WSDL

pălării 23 iulie 2013 la 13:09

Scrierea unei aplicații SOAP client-server în PHP

  • PHP
  • Tutorial

Salutare tuturor!
S-a întâmplat că recent 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 Declarație de problemă

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 de trimitere de mesaje SMS și, mai precis, vom primi mesaje din diferite surse prin protocolul SOAP. După care, vom lua în considerare sub ce formă vin pe server. Procesul de a pune în coadă mesajele pentru trimiterea ulterioară către furnizor, din păcate, depășește scopul acestei postări din mai 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
  • textul mesajului SMS.
Î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 vă vine 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:

  • Numar 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 permite utilizarea unui număr mic de resurse de rețea cu un număr mare de metode și un 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 ele acceptând și procesează 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 Arsenalul nostru include imediat întreaga putere a unui teanc de tehnologii bazate pe acest limbaj de marcare, și anume XML-Schema - un limbaj pentru descrierea structurii unui document XML (mulțumesc Wikipedia!), care permite validarea automată a datelor primite de server. de la clienti.

Ș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 peste orice protocol la nivel de aplicație și nu doar în combinație 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 optional. Î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(Limbajul de descriere a serviciilor web). Da, da, acesta este exact lucrul care ne sperie pe cei mai mulți dintre noi chiar și de a încerca 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, bazat pe 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 fișier este î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 atât de înfricoșător pe cât 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.

Sarcina principală a 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 de.
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 clientului un fișier WSDL cu tipul MIME corect. 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 „ abordare» 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. Acestea. 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 ( Operațiune) 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 tipul " SMSServicePortType"și în elementul" portType„cu denumirea de același tip, indicăm legarea procedurilor de mesaje. Și astfel, mesajul primit (de la client la server) va fi numit „ 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 - „ Raspuns».

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 toate acțiunile ulterioare să se întâmple în același mod ca și pentru mine, 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ă copiați pur și simplu conținutul său 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 cea mai simplă modalitate ar fi să organizați o matrice în interiorul elementului messageList! Să o facem:

// 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 în 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 obține structura corectă de date pe server?” Dar vă sugerez să nu disperați și să încercați să convertiți matricea noastră la tipul un 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" => object(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 a 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;
  • vă puteți scrie propriul server care comunică 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 mai puțin rău decât 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).

Elementele de extensie de legare sunt utilizate pentru a specifica o gramatică specifică pentru mesajele de eroare (3) primite (3) și trimise (4) (5). De asemenea, pot fi specificate informații despre nivelul de operare (2) și nivelul obligatoriu (1).

Elementul de legare a operațiunii conține date pentru funcționarea cu același nume a tipului de port asociat. Cu toate acestea, numele operațiunii nu este, în general, unic (de exemplu: metode de supraîncărcare / funcții - folosind aceleași nume cu semnături diferite), prin urmare poate să nu fie suficient pentru a determina în mod unic operațiunea țintă a tipului de port. În astfel de cazuri, operațiunea țintă este adresată prin specificarea suplimentară a numelor adecvate ale elementelor wsdl:input și wsdl:output folosind atributul name.

Legare trebuie sa instalați un singur protocol.

Legare nu ar trebui conțin informații despre adresă.

Port

Un port definește un singur punct final prin setarea unei adrese la care să se lege.

  1. <wsdl:definiții .... >
  2. <wsdl:serviciu .... > *
  3. <wsdl:port name = "nmtoken" binding = "qname" > *
  4. <-- extensibility element (1) -->
  5. wsdl:port>
  6. wsdl:serviciu>
  7. wsdl:definiții>

Atributul name specifică un nume unic printre toate porturile din documentul WSDL. Atributul de legare de tip QName conține o referință la legare (vezi).

Elementele de extensie (1) sunt utilizate pentru a specifica adresa.

Port nu ar trebui specificați mai multe adrese.

Port nu ar trebui conține orice informații obligatorii, altele decât o adresă.

Serviciu

Un serviciu reunește un set de porturi asociate.

  1. <wsdl:definiții .... >
  2. <wsdl:serviciu nume = "nmtoken" > *
  3. <wsdl:port .... /> *
  4. wsdl:serviciu>
  5. wsdl:definiții>

Atributul name specifică un nume unic printre toate serviciile definite în documentul WSDL.

Porturile din cadrul unui serviciu sunt conectate după cum urmează:

  • Porturile nu comunică între ele (adică ieșirea unui port nu este intrarea altuia).
  • Dacă un serviciu are mai multe porturi care partajează un tip de port comun, dar utilizează legături diferite sau au adrese diferite, acele porturi sunt porturi alternative. Fiecare astfel de port implementează un comportament logic echivalent (în cadrul constrângerilor de transport și format de mesaj impuse de legarea corespunzătoare). Acest lucru permite clientului să selecteze un port specific pentru comunicare pe baza diferitelor criterii (suport protocol de transport etc.).
  • Privind porturile, puteți determina ce tipuri de porturi sunt acceptate de serviciu. Pe baza acestor date, clientul poate determina capacitatea de a interacționa cu un anumit serviciu. Acest lucru este util dacă există o conexiune între operațiunile din diferite tipuri de porturi, iar serviciul trebuie să accepte toate tipurile de porturi necesare pentru a efectua o anumită sarcină.
  1. Aceasta este o traducere gratuită, parțială, extinsă a documentului Web Services Description Language (WSDL) 1.1 din 15 martie 2001
  2. Este extrem de incomod să operezi cu termeni indeclinabili scrisi în latină și, de asemenea, sunt traduși fără ambiguitate. Prin urmare, numele original este dat numai atunci când este introdus un termen nou, iar mai departe în text este folosită traducerea în limba rusă.

WSDL (Limbajul de descriere a serviciilor web) versiunea 1.1 a fost publicată pe 15 martie 2001. WSDL este un format bazat pe XML folosit pentru a descrie serviciile web folosind mesaje care conțin informații despre cum să accesați un anumit serviciu web. WSDL extensibil, care vă permite să descrieți serviciile și mesajele acestora, indiferent de formatele de mesaje sau protocoalele de rețea utilizate pentru transport, cu toate acestea, WSDL 1.1 este cel mai des folosit împreună cu SOAP 1.1, HTTP GET/POST și MIME. Deoarece WSDL a fost dezvoltat în comun cu SOAP, iar la dezvoltarea sa au participat aceleași companii Microsoft, Ariba și IBM. Dacă luăm în considerare documentul WSDL intuitiv, putem spune că permite raspunde la 4 intrebari:

1) ce faci? Răspunsul la această întrebare este dat într-o formă potrivită atât pentru percepția umană, cât și pentru o formă perceptibilă de mașină. Răspuns pentru persoana din etichete:<Nume/>, <documentație/>, pentru masina -<mesaj/>, <pointType>

2) Ce limbă vorbiți? (ce tipuri utilizați?) Răspundeți în etichetă:<tipuri/>

3) Cum voi comunica cu tine? (cum va accesa clientul serviciul web?): HTTP sau SMTP. Răspunsul constă în<legare/>

4) unde te pot găsi? (unde pot găsi acest serviciu web sau care este adresa URL a acestuia?). Raspunsul este:<serviciu/>

Structura:

Fiecare document WSDL poate fi împărțit în trei părți logice:

1. definirea tipurilor de date - determinarea tipului de mesaje trimise și primite de serviciul XML

2. operații abstracte - lista de operatii care pot fi efectuate cu mesaje

3. legarea serviciului - metoda prin care va fi livrat mesajul

Documentație WSDL poate fi creat manual, dar limbajul este strict formalizat WSDL vă permite să automatizați procesul de scriere WSDL-documente. Multe instrumente de creare a serviciilor Web conțin utilitare care creează automat WSDL-fișiere care descriu servicii Web gata făcute. De exemplu, Web Services Authoring Tool Apache Axis conţine o clasă Java2WSDL, crearea WSDL- un fișier dintr-o clasă sau interfață Java care descrie un serviciu Web. Pachetul IBM WSTK, care include Axă, conține utilitatea java2wsdl, care creează și rulează un obiect din această clasă. Funcționează din linia de comandă.

Elemente de document WSDL

Să descriem cele mai frecvent utilizate etichete WSDL:

Etichetă este eticheta rădăcină a tuturor documentelor WSDL. Acesta definește mai multe spații de nume:

1) spațiu de nume țintă este spațiul de nume al serviciului nostru web

2) xmlns – spațiu de nume de document WSDL standard

3)xmlns: SOAP_ENC – spațiu de nume folosit pentru a descrie codificarea SOAP


4) xmlns: impl și intf – spațiul de nume al implementării și definiției serviciului nostru web

· Document de definire a serviciului web

· Document pentru implementarea unui serviciu web

Pentru simplitate, de regulă, folosesc 1 fișier care conține toate informațiile

Element - furnizează informații despre datele care sunt transferate de la un punct final la altul.

Pentru a descrie un apel RPC, trebuie să creați un mesaj de intrare și un mesaj de ieșire.

În cadrul acestui element, puteți specifica parametrii metodei folosind elementul

Element descrie și definește operațiunile sau metodele suportate de un serviciu web

Operațiile pot avea mesaje de intrare, precum și mesaje de eroare.

Element - descrie modul în care operațiunile specificate într-un tip de port vor fi transmise prin rețea. Deoarece elementul folosește un tip de port, trebuie să specifice un tip definit undeva mai devreme în document.

Element - indică unde se găsește serviciul web

Element import . Foarte des, elementul de serviciu este alocat documentului său wsdl din motive practice.

Pentru a permite combinarea mai multor documente wsdl într-unul singur, se folosește elementul de import. Vă permite să includeți un document wsdl în altul.

Element tipuri vă permite să specificați tipurile de date transmise dacă acestea nu sunt standard.

WSDL acceptă 4 moduri de operare:

· operațiuni unidirecționale sau unidirecționale. Mesajul este trimis la punctul final al serviciului. În acest caz, operația este descrisă de un singur mesaj de intrare.

· Request-Response – modul cerere-răspuns. Acest mod de operare este cel mai comun. În acest mod, descrierea operațiunii conține un mesaj de intrare și de ieșire și un mesaj de eroare opțional.

· Operațiune de tip cerere-răspuns. În acest mod, un punct final este un client al altui punct final. Formatul de operare este similar cu modul cerere-răspuns, dar datele de ieșire sunt listate înaintea datelor de intrare.

· Notificare de operare. Acest mod este o altă versiune a primitivei de transmisie unidirecțională, în care punctul final trimite mesajul mai degrabă decât să-l primească. Operația conține doar un mesaj de ieșire.

Pagina 2 din 3

Descriere folosind WSDL

SOAP funcționează foarte bine dacă se știe totul despre serviciul Web. Cu toate acestea, acest lucru nu este întotdeauna cazul. Mijlocul de descriere a interfeței pentru accesarea unui serviciu Web este limbajul WSDL (Web Services Description Language). Acest standard a fost dezvoltat în comun de IBM, Microsoft și webMethods. Fiecare dintre aceste trei companii a avut propria abordare pentru a dezvolta un standard pentru descrierea serviciilor Web: IBM a creat NASSL, Microsoft a dezvoltat SCL, iar webMethods a creat WIDL.

Rezultatul colaborării lor a fost versiunea 1.1 a limbajului WSDL.În ceea ce privește W3C, trebuie menționat că, ca și în cazul SOAP, consorțiul W3C bazat pe versiunea 1.1 a dezvoltat WSDL 1.2, care este acum o recomandare W3C. Descrierea WSDL a unui serviciu Web conține toate informațiile necesare utilizării serviciului, inclusiv metodele disponibile și parametrii acestora. Aceste informații sunt cuprinse în următoarele cinci elemente:

  • - protocoale suportate.
  • - Mesaje de serviciu web (cerere, răspuns).
  • Toate metodele disponibile.
  • - URI serviciu.
  • - tipuri de date utilizate.

Toate aceste informații sunt stocate în elementul rădăcină al descrierii WSDL Lista de mai jos prezintă un exemplu de descriere WSDL a unui serviciu Web.

Descrierea WSDL a serviciului Web

Da... nu vă puteți da seama fără un pahar, dar acesta este unul dintre cele mai simple (!) fișiere WSDL. Din păcate, unul dintre dezavantajele extensiei SOAP pentru PHP 5 este că, spre deosebire de alte implementări SOAP, nu generează automat descrieri WSDL (cel puțin nu încă). Cu siguranță acest defect va fi corectat în versiunile viitoare de PHP.

Apropo!

Pentru a genera automat descrierea WSDL, puteți utiliza implementări alternative ale protocolului SOAP în PHP:

Căutare în director folosind UDDI

Acum că știm cum să obținem informații despre un serviciu web și cum să-l interogăm, trebuie să învățăm cum să găsim un astfel de serviciu. În acest scop există ceva asemănător Paginilor Aurii și anume registrele UBR (Registrele Universale de Afaceri) - directoare de servicii web.

Există mai multe astfel de registre, inclusiv cele ale IBM, Microsoft, NTT-Com și SAP. Aceste registre își sincronizează datele, astfel încât să puteți utiliza oricare dintre ele. Versiunea actuală a standardului UDDI este UDDI 3.0, deși majoritatea implementărilor folosesc versiunea 2. Dezvoltatorii acestui standard includ companii gigantice precum HP, Intel, Microsoft și Sun.

Pentru a interacționa cu UBR există două tipuri de API: Inquiry API și Publish API. Interfață Inquiry API (Solicitare) este pentru solicitare servicii în registrele UBR și interfața Publish API permite dezvoltatorilor să-și înregistreze serviciile. Se pare că este doar o chestiune de timp până când conținutul registrelor se umple cu spam :)

Apropo!

Există registre de testare concepute pentru a testa înregistrările de servicii înainte de a le plasa în registrele „adevărate”.

Iată cum arată o solicitare de serviciu web:

sortByNameAsc sortByDateDesc %guid%

În exemplul de mai sus, puteți vedea că cererea UDDI este încapsulată într-un mesaj SOAP, așa că pare destul de familiar. Răspunsul la cerere este, de asemenea, un document SOAP, prezentat mai jos:

Tur ghidat al serviciilor web Exemple de servicii web pentru ghidul de turism Tur ghidat Serviciul de cotații

Instalare

Instalarea extensiei SOAP pentru PHP5 este destul de ușoară. Pe Windows, acest modul se află în subdirectorul ext al directorului de instalare PHP. Pentru a-l folosi, trebuie să adăugați următoarea linie la fișierul php.ini: extensie=php_soap.dll Pentru a funcționa, acest modul necesită ca acesta să fie inclus implicit în PHP 5, cel puțin în versiunea Windows.

  • Tutorial

Salutare tuturor!
S-a întâmplat că recent 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 Declarație de problemă

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 de trimitere de mesaje SMS și, mai precis, vom primi mesaje din diferite surse prin protocolul SOAP. După care, vom lua în considerare sub ce formă vin pe server. Procesul de a pune în coadă mesajele pentru trimiterea ulterioară către furnizor, din păcate, depășește scopul acestei postări din mai 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
  • textul mesajului SMS.
Î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 vă vine 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:

  • Numar 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 permite utilizarea unui număr mic de resurse de rețea cu un număr mare de metode și un 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 ele acceptând și procesează 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 Arsenalul nostru include imediat întreaga putere a unui teanc de tehnologii bazate pe acest limbaj de marcare, și anume XML-Schema - un limbaj pentru descrierea structurii unui document XML (mulțumesc Wikipedia!), care permite validarea automată a datelor primite de server. de la clienti.

Ș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 peste orice protocol la nivel de aplicație și nu doar în combinație 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 optional. Î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(Limbajul de descriere a serviciilor web). Da, da, acesta este exact lucrul care ne sperie pe cei mai mulți dintre noi chiar și de a încerca 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, bazat pe 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 fișier este î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 atât de înfricoșător pe cât 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.

Sarcina principală a 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 de.
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 clientului un fișier WSDL cu tipul MIME corect. 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 „ abordare» 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. Acestea. 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 ( Operațiune) 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 tipul " SMSServicePortType"și în elementul" portType„cu denumirea de același tip, indicăm legarea procedurilor de mesaje. Și astfel, mesajul primit (de la client la server) va fi numit „ 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 - „ Raspuns».

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 toate acțiunile ulterioare să se întâmple în același mod ca și pentru mine, 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ă copiați pur și simplu conținutul său 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 cea mai simplă modalitate ar fi să organizați o matrice în interiorul elementului messageList! Să o facem:

// 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 în 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 obține structura corectă de date pe server?” Dar vă sugerez să nu disperați și să încercați să convertiți matricea noastră la tipul un 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" => object(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 a 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;
  • vă puteți scrie propriul server care comunică 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 mai puțin rău decât 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).