Sapunul este usor

SOAP-ul este ușor

Destul de ciudat, dar SOAP (S O aplicare bject A P rotocol ccesul, cross-platform, cross-limbaj obiecte de tehnologie de pornire) - este foarte ușor, dar când am început să lucrez cu el la Delphi, nu putea da seama care parte să se apropie de el. De fapt, proiectarea de aplicatii SOAP, trebuie să îndeplinească condițiile destul de un pic, și apoi totul va funcționa bine, iar aceste condiții simple și voi încerca să abordeze aici.







Condiția principală pentru programarea SOAP: serverul trebuie să fie apatrid. și anume rezultatul interogării nu trebuie să depindă de comenzile anterioare primite de server. Aceasta înseamnă că toți parametrii sesiunilor trebuie să fie stocați pe client și să fie trimiși serverului ca parte a solicitării (dacă este necesar). Acest lucru asigură o stabilitate și o scalabilitate ridicată a sistemului, deși o serie de delicii ale sistemului convențional cu două legături devin indisponibile:
  • Nu puteți gestiona în mod explicit tranzacțiile de la client (acesta este serverul),
  • prin urmare, nu puteți bloca înregistrarea pentru timpul de editare (cu excepția cazului în care faceți flag-uri speciale în baza de date)
  • Este imposibil ca parametrii să fie transferați de o comandă, iar altul să ia în considerare rezultatul - totul ar trebui să se întâmple în cadrul aceleiași comenzi
  • Nu puteți lucra cu banda clasică a părții principale (cu toate acestea, TClientDataset oferă un instrument excelent pentru acest lucru: seturi de date imbricate - tabele imbricate),
  • Nu puteți utiliza proprietatea ClientDataSet.PacketRecords> 0. serverul "nu-și amintește" ce a trimis deja clientului și ce nu - o astfel de funcționalitate trebuie implementată utilizând parametri suplimentare de interogare,
  • . dacă am uitat ceva, o să termin mai târziu.

Aplicație simplă SOAP

Exemple similare sunt luate în considerare în orice literatură dedicată dezvoltării SOAP pe Delphi.
Rulați Delphi și selectați File | Nou | Altele. . accesați fila WebServices și selectați aplicația Server de săpun.

Veți fi oferit o gamă de 5 opțiuni:
  • ISAPI / NSAPI Dinamic Link Libarry este o bibliotecă plug-in pentru serverele IIS / Netscape, fiecare cerere fiind transmisă ca structură și procesată printr-un fir separat,
  • CGI Stand-alone Executable - aplicație consola, primește o cerere pentru o intrare standard, returnează un răspuns la ieșirea standard, fiecare cerere este procesată de o instanță de aplicație separată,
  • Win-CGI Stand-alone executable - aplicație Windows, schimbul de date se face prin fișier INI (nu este recomandat pentru utilizare, ca fiind depășit),
  • Apache Modulul partajat (DLL) este o bibliotecă plug-in pentru serverul Apache, fiecare cerere fiind trecută ca o structură și procesată printr-un fir separat,
  • WebAppDebugger executabilă - link-ul de bibliotecă pentru depanare nave de server cu Delphi, ca WebAppDebugger este, de asemenea, un server COM, trebuie să specificați (arbitrar) CoClass nume pentru obiectul COM prin care va fi cauzate de modul dvs. de web.

Selectați CGI Stand-alone Executable, ca fiind cel mai simplu pentru formatul de depanare, apoi aplicația poate fi ușor transformată în orice altă. Trucul este că, dacă toate logica aplicației este concentrată în module scrise de tine, pur și simplu creați o nouă aplicație de tipul necesar, conectați la Nimu modulele lor, și funcționează!

După ce faceți clic pe OK, va fi generată o nouă aplicație care conține un WebModule cu trei componente:

  • THTTPSoapDispatcher - primește pachetele SOAP primite și le transmite către componenta definită de proprietatea Dispecer (de obicei THTTPSoapPascalInvoker),
  • THTTPSoapPascalInvoker - primește o cerere SOAP de intrare, găsește Invocarea Registry numita metodă (Executa invocă) care generează un răspuns și îl trimite obrabno THTTPSoapDispatcher,
  • TWSDLHTMLPublish - generează WSDL (W eb Services D escription L anguage), o descriere a datelor și interfețelor suportate de modulul dumneavoastră.

Salvați aplicația creată, acesta va fi scheletul serverului nostru.

Îl vom umple cu logică. Deoarece serverul și clientul vor trebui să descrie structurile datelor și interfețelor transmise, este mai bine să le punem într-un modul separat, iar implementarea întregului server în altul. Pentru a face acest lucru, creați două module (File | New | Unit) și salvați unul dintre acestea sub numele CentimeterInchIntf.pas. și altul - CentimeterInchImpl.pas. În interiorul CentimeterInchIntf.pas tastați următoarele:

Așadar, am definit interfața ICmInch, care oferă două funcții: convertirea centimetrilor în inci și inci în centimetri și înregistrarea în InvokeRegistry.

Să abordăm implementarea. În CentimeterInchImpl.pas, definim descendentul TInvokableClass care implementează interfața noastră ICmInch:







După cum puteți vedea, am implementat în TCmInch ambele funcții ICmInch interfață, și, de asemenea înregistrat noua clasa invokable în InvokeRegistry (în general, tot ce vor fi transmise în rețea trebuie să fie înregistrate în ea, cu excepția tipurilor scalare).

Listarea WebService

Dacă faceți clic pe linkul WSDL pentru ICmInch. atunci primim o descriere WSDL completă a interfeței noastre.

Creați o nouă aplicație (de tip obișnuit), specificați în secțiunea noastră de utilizare modulul de interfață CentimeterInchIntf. Plasați cele două butoane, două câmpuri de introducere și componenta THTTPRIO din paleta WebServices din formularul principal.

Î: Și dacă serverul SOAP este scris de altcineva și nu avem un modul de interfață?
R: Apoi trebuie să utilizați importatorul de servicii web, care este localizat în fișierul | | Nou | Altele. . în fila WebServices. Acest expert va genera un modul de interfață pentru serviciul WSDL.

Transmiterea tipurilor complexe

componenta noastră THTTPSOAPPascalInvoker știe deja cum de a transmite tipuri scalare și matrice dinamice (acestea din urmă trebuie să fie pre-înregistrate în InvokeRegistry, cm. de mai jos), dar pentru transportul de tipuri de complexe, cum ar fi matrice statică, interfață, înregistrare, setați sau clasă, mai întâi este necesar pentru a le descrie ca urmași clasa TRemotable. care are informații de tip RunTime (RTTI). De exemplu, dacă dorim să declarăm o clasă care returnează rata monedei și numele său, modul nostru de interfață va arăta astfel:

Aici am declarat în plus și matricea dinamică TCurrencyArray, în cazul în care dorim să o transferăm (rețineți diferența dintre comenzile de clasă și de înregistrare în matrice).
De fapt, sintaxa completă a comenzii de înregistrare a clasei este ceva mai largă, cei care doresc pot citi despre aceasta în documentația Delphi:

Notă: În cazul în care există un tip care un document WSDL este un scalar, dar nu are corespondență directă în Object Pascal (de exemplu, DateTime) apoi ca clasa de bază care trebuie utilizată TRemotableXS, care declară două metode XSToNative și NativeToXS pentru a converti reprezentarea șir în Object Pascal și înapoi (aceste metode trebuie, bineînțeles, să fie puse în aplicare).
Delphi include modulul XSBuiltIns, care are deja multe funcții utile (dar în versiunea 6.0 au existat erori în procesarea datei, dacă setările naționale din sistem nu erau engleze).

Există o întrebare interesantă cu crearea-distrugerea obiectelor transmise ca parametri. Iată ce spune documentația TRemotable despre el:
„De la serverul descendenții TRemotable sunt parametrii de intrare sunt create în mod automat în timpul despachetarea (unmarshal) metoda de apel, și se elimină automat după ambalare parametrii de ieșire (Marshal) pentru transmiterea către client.
Descendenții descendenți creați în cadrul unei metode numite printr-o interfață invocabilă sunt șterse automat după ce valoarea lor este împachetată (marshal) pentru transmiterea către client.
Clientul care invocă interfața invocabilă este responsabil pentru crearea obiectelor utilizate ca parametri de intrare și pentru distrugerea tuturor descendenților care au creat, precum și a celor care rezultă din apelul de metodă. "

Transfer de date

Aici totul este simplu. În timp ce vă aflați în proiectul Application Server Soap, selectați File | Nou | Altele. . accesați fila WebServices și selectați Modulul de date pentru serverul de săpun. Dezvoltarea în continuare nu este diferită de aplicarea convențională MIDAS, cu două caracteristici: serverul trebuie să fie apatrid - primit solicitarea, am spus uitat (de exemplu, modulul CGI literalmente după fiecare apel este finalizată), și să nu aibă mai mult de un SoapDataModule.
Plasați componentele de acces la date pe modulul rezultat (de exemplu, TClientDataset), setați toate proprietățile necesare pentru lucrare. Plasați TDataSetProvider, conectați-l la componenta de acces la date.

Compilați aplicația și puneți-o unde poate fi rulată de serverul Web (din anumite motive nu am putut rula sub WebAppDebugger).

Aplicația client pus pe forma și TSoapConnection TClientDataset, în SoapConnection.URL introduceți calea către interfața serverului dvs.: puteți utiliza un anumit SoapDataModule interfață, și poate fi mai general - IAppServer. La punctul TClientDataset.RemoteServer la TSoapConnection. Acum, punând TClientDataset.Active:=true, vom obține datele noastre pe client.

Dacă necesită unele parametri pentru a deschide un server de pe server, va fi convenabil în loc să setați Active: = true pentru a utiliza solicitarea DataRequest. Arată așa.
Pe client: Pe server:

Dacă schimbați datele de pe client și doriți să le salvați la server - apel în ApplyUpdates metoda TClientDataset, pur și simplu nu instalați în TDataSetProvider.ResolveToDataSet = true. cererile de actualizare, chiar dacă el formează TDataSetProvider, și controlul asupra formării acestor cereri se poate face prin proprietăți TField.ProviderFlags.

Pentru curiozitate: formatul pachetului de date transmis este descris pe site-ul community.borland.com. dar în realitate este trecut în forma unui pachet binar (base64Binary) în același format ca și fișierul (* .cds), nu am putut găsi descrierea acestui format.
Pentru a vedea cum arată într-adevăr pachetele transmise prin rețea, puteți folosi programul tcpTrace. sau jurnalul WebAppDebugger.

Lucrul cu partea principală

Și aici, totul este simplu, dar este oarecum neobișnuit, deoarece partea ar trebui transferată ca o îmbinare în setul de date de bază, deoarece piesa de bază obișnuită pentru TClientDataSet este imposibilă. Acest lucru se face astfel.

Modulul de date pentru serverul de săpun conține datele pentru tabela de master și pentru detaliu și, ca de obicei, este conectat prin intermediul TDataSource. Unul din TDatasetProvider este plasat acolo, care este asociat cu tabela master. Serverul este compilat și pus unde poate fi lansat de serverul Web.

În cel de-al doilea TClientDataSet (aceasta va fi partea noastră) setați singura proprietate: DataSetField (selectați numele pentru TDataSetField al primului set de date din listă). Acum, dacă conectăm TClientDataSet cu grilele, atunci vom vedea datele noastre - separat tabela master și detalii.

Există o opțiune alternativă: comandantul și partea sunt transferate prin depozite separate de date, iar partea este încărcată în întregime. și pentru a selecta setul de înregistrări de piese care corespund unei anumite linii a expertului, se folosește filtrarea pe client, cu toate acestea, vor exista probleme cu actualizarea sincronă a expertului și a detaliilor.

Ca o literatură suplimentară vă sfătuiesc să arătați:
  1. Capitolul BizSnap al Ghidului dezvoltatorului Kylix (în special părțile 4-6)
  2. InterBase într-o lume multi-nivel
  3. Proiectarea aplicatiilor ISAPI pentru lucrul cu bazele de date
  4. . și bineînțeles - RTFM. adevăr cu căutarea în aceste secțiuni din anumite motive mari probleme, dar informațiile din ajutor este, de asemenea, destul de detaliate,
  5. precum și acele aplicații demo care vin împreună cu Delphi

Dorințele pentru elaborarea acestui articol sunt binevenite la: [email protected]







Articole similare

Trimiteți-le prietenilor: