Liriskā daļa.

Iedomājieties, ka esat ieviesis vai ieviešat noteiktu sistēmu, kurai vajadzētu būt pieejamai no ārpuses. Tie. ir noteikts serveris, ar kuru jums ir jāsazinās. Piemēram, tīmekļa serveris.

Šis serveris var veikt daudzas darbības, strādāt ar datu bāzi, veikt dažus trešo pušu pieprasījumus citiem serveriem, veikt dažus aprēķinus utt. dzīvot un, iespējams, attīstīties pēc viņam zināmā scenārija (t.i., pēc izstrādātāju scenārija). Cilvēkam nav interesanti sazināties ar šādu serveri, jo viņš var nespēt/gribēt nodrošināt skaistas lapas ar attēliem un citu lietotājam draudzīgu saturu. Tas ir uzrakstīts un darbojas, lai strādātu un sniegtu datus, kad tam tiek prasīts, neuztraucoties, ka tas ir lasāms cilvēkiem, klients ar to tiks galā pats.

Citas sistēmas, piekļūstot šim serverim, jau var rīkoties ar no šī servera saņemtajiem datiem pēc saviem ieskatiem – apstrādāt, uzkrāt, izsniegt saviem klientiem utt.

Viena no iespējām sazināties ar šādiem serveriem ir SOAP. SOAP xml ziņojumu apmaiņas protokols.

Praktiskā daļa.

Tīmekļa pakalpojums (tas ir nosaukums tam, ko serveris nodrošina un ko izmanto klienti) ļauj sazināties ar serveri, izmantojot skaidri strukturētus ziņojumus. Fakts ir tāds, ka tīmekļa pakalpojums nepieņem nekādus datus. Tīmekļa pakalpojums atbildēs ar kļūdu uz jebkuru ziņojumu, kas neatbilst noteikumiem. Kļūda, starp citu, būs arī xml formā ar skaidru struktūru (kas gan neatbilst patiesībai ziņojuma tekstā).

WSDL (Web Services Description Language). Noteikumi, pēc kuriem tiek sastādīti ziņojumi tīmekļa pakalpojumam, ir aprakstīti arī, izmantojot xml, un tiem ir arī skaidra struktūra. Tie. Ja tīmekļa pakalpojums nodrošina iespēju izsaukt metodi, tam jāļauj klientiem uzzināt, kādi parametri tiek izmantoti šai metodei. Ja tīmekļa pakalpojums kā parametru sagaida virkni Method1 un virknei jābūt nosauktai Param1, šie noteikumi tiks norādīti tīmekļa pakalpojuma aprakstā.

Kā parametrus var nodot ne tikai vienkāršus tipus, bet arī objektus un objektu kolekcijas. Objekta apraksts ir saistīts ar katras objekta sastāvdaļas aprakstu. Ja objekts sastāv no vairākiem laukiem, tad tiek aprakstīts katrs lauks, tā veids, nosaukums (kādas ir iespējamās vērtības). Lauki var būt arī kompleksa tipa un tā tālāk, līdz tipu apraksts beidzas ar vienkāršiem - virkne, Būla, skaitlis, datums... Tomēr daži konkrēti veidi var izrādīties vienkārši, svarīgi, lai klienti var saprast, kādas vērtības tie var saturēt.

Klientiem pietiek zināt tīmekļa pakalpojuma url, blakus vienmēr būs wsdl, no kura var gūt priekšstatu par metodēm un to parametriem, ko šis tīmekļa pakalpojums nodrošina.

Kādas ir visu šo zvanu un svilpienu priekšrocības:

  • Lielākajā daļā sistēmu metožu un veidu apraksts notiek automātiski. Tie. servera programmētājam tikai jāpasaka, ka šo metodi var izsaukt, izmantojot tīmekļa pakalpojumu, un wsdl apraksts tiks ģenerēts automātiski.
  • Apraksts, kuram ir skaidra struktūra, ir lasāms jebkuram ziepju klientam. Tie. neatkarīgi no tīmekļa pakalpojuma klients sapratīs, kādus datus tīmekļa pakalpojums saņem. Izmantojot šo aprakstu, klients var izveidot savu iekšējo objektu klašu struktūru, t.s. iesiešana" un. Rezultātā programmētājam, kas izmanto tīmekļa pakalpojumu, ir jāraksta kaut kas līdzīgs (pseidokods):

    NewUser:=TSoapUser.Create("Vasja","Kirēns","administrators"); ziepes.PievienotLietotājs(Jauns lietotājs);

  • Automātiska apstiprināšana.

    • xml validācija. xml ir jābūt labi noformētam. Nederīgs xml — nekavējoties kļūda klientam, ļaujiet viņam to sakārtot.
    • shēmas validācija. xml ir jābūt noteiktai struktūrai. xml neatbilst shēmai - uzreiz kļūda klientam, ļaujiet viņam to sakārtot.
    • Datu pārbaudi veic ziepju serveris, lai datu veidi un ierobežojumi atbilstu aprakstam.
  • Autorizāciju un autentifikāciju var īstenot, izmantojot atsevišķu metodi. natively. vai izmantojot http autorizāciju.
  • Tīmekļa pakalpojumi var darboties gan caur ziepju protokolu, gan caur http, tas ir, izmantojot saņemšanas pieprasījumus. Tas ir, ja parametri ir vienkārši dati (bez struktūras), tad varat vienkārši izsaukt parasto get www.site.com/users.asmx/GetUser?Name=Vasia vai post. Tomēr tas nav visur un ne vienmēr.
  • ... skatīt Vikipēdijā

Ir arī daudz trūkumu:

  • Nepamatoti liels ziņojuma izmērs. Nu šeit jau pati xml būtība ir tāda, ka formāts ir lieks, jo vairāk tagu, jo vairāk nederīgas informācijas. Plus ziepes palielina savu atlaišanu. Intraneta sistēmām trafika problēma ir mazāk aktuāla nekā internetam, tāpēc ziepes vietējiem tīkliem ir pieprasītākas, jo īpaši Sharepoint ir ziepju tīmekļa pakalpojums, ar kuru jūs varat veiksmīgi sazināties (un daži ierobežojumi).
  • Automātiska tīmekļa pakalpojuma apraksta maiņa var sabojāt visus klientus. Nu, tā ir jebkurai sistēmai, ja netiek atbalstīta atgriezeniskā savietojamība ar vecajām metodēm, viss izkritīs...
  • Nevis mīnuss, bet trūkums. Visiem metožu izsaukumiem jābūt atomiem. Piemēram, strādājot ar datu bāzi, mēs varam sākt darījumu, izpildīt vairākus vaicājumus, pēc tam veikt atcelšanu vai apņemšanos. Nav darījumu ar ziepēm. Viens pieprasījums, viena atbilde, saruna beigusies.
  • Tikt galā ar aprakstu, kas atrodas servera pusē (vai viss ir pareizi aprakstīts?) un to, kas ir klienta (kas man šeit tika aprakstīts?), var būt diezgan sarežģīti. Bija vairākas reizes, kad nācās saskarties ar klienta pusi un pārliecināt servera programmētāju, ka viņa dati ir aprakstīti nepareizi, bet viņš no tā vispār neko nevarēja saprast, jo automātiskā ģenerēšana un viņam nevajadzētu, tas ir jautājums programmatūra. Un kļūda, protams, bija metodes kodā; programmētājs to vienkārši neredzēja.
  • Prakse rāda, ka tīmekļa pakalpojumu izstrādātāji ir šausmīgi tālu no cilvēkiem, kas izmanto šos tīmekļa pakalpojumus. Atbildot uz jebkuru pieprasījumu (derīgs no ārpuses), var parādīties nesaprotama kļūda “Kļūda 5. Viss ir slikti”. Viss atkarīgs no izstrādātāju sirdsapziņas :)
  • Esmu pārliecināts, ka joprojām kaut ko neatceros...

Piemēram, ir atvērts tīmekļa pakalpojums belavia:

  • http://86.57.245.235/TimeTable/Service.asmx - ieejas punkts, ir arī teksta apraksts par metodēm trešo pušu izstrādātājiem.
  • http://86.57.245.235/TimeTable/Service.asmx?WSDL - wsdl saņemto un atgriezto datu metožu un veidu apraksts.
  • http://86.57.245.235/TimeTable/Service.asmx?op=GetAirportsList - konkrētas metodes apraksts ar xml pieprasījuma un xml atbildes veida piemēru.

Varat manuāli izveidot un nosūtīt pieprasījumu, piemēram:

POST /TimeTable/Service.asmx HTTP/1.1 Host: 86.57.245.235 Content-Type: text/xml; charset=utf-8 Content-Length: garums SOAPAction: "http://webservices.belavia.by/GetAirportsList" ru

atbilde nāks:

HTTP/1.1 200 OK Datums: Pirmdiena, 2013. gada 30. septembris 00:06:44 GMT Serveris: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 4.0.30319 Kešatmiņas kontrole: privāta, maks. -age=0 Satura veids: teksts/xml; charset=utf-8 Satura garums: 2940

PS Iepriekš tika atvērts Aeroflot tīmekļa pakalpojums, taču pēc tam, kad 1C pievienoja ziepju atbalstu 8ku, virkne 1C beta testētāju to veiksmīgi instalēja. Tagad tur kaut kas ir mainījies (adresi nezinu, ja interesē, varat pameklēt).
ZZY Atruna. Viņš runāja ikdienas līmenī. Jūs varat spert.

Sveiki visiem!
Tā notika, ka nesen es sāku izstrādāt tīmekļa pakalpojumus. Bet šodien tēma nav par mani, bet par to, kā mēs varam uzrakstīt savu XML Web Service, pamatojoties uz SOAP 1.2 protokolu.

Es ceru, ka pēc tēmas izlasīšanas jūs varēsiet:

  • uzrakstiet savu tīmekļa lietojumprogrammas servera implementāciju;
  • uzrakstiet savu tīmekļa lietojumprogrammas klienta implementāciju;
  • uzrakstiet savu tīmekļa pakalpojuma aprakstu (WSDL);
  • nosūtīt klienta masīvus ar tāda paša veida datiem uz serveri.

Kā jau varēja uzminēt, visas maģijas tiks veiktas, izmantojot PHP un iebūvētās SoapClient un SoapServer klases. Mūsu trusis būs SMS īsziņu sūtīšanas serviss.

1 Problēmas izklāsts

1.1 Robežas

Sākumā es ierosinu tikt galā ar rezultātu, ko sasniegsim tēmas beigās. Kā ziņots iepriekš, mēs rakstīsim SMS īsziņu sūtīšanas pakalpojumu, un, precīzāk, mēs saņemsim ziņas no dažādiem avotiem, izmantojot SOAP protokolu. Pēc tam mēs apsvērsim, kādā formā tie nonāk serverī. Diemžēl daudzu iemeslu dēļ ziņojumu ievietošana rindā tālākai piegādei pakalpojumu sniedzējam ir ārpus šīs ziņas darbības jomas.

1.2 Kādus datus mēs mainīsim?

Lieliski, esam izlēmuši par robežām! Nākamais solis, kas jāveic, ir izlemt, ar kādiem datiem mēs apmainīsimies starp serveri un klientu. Par šo tēmu es iesaku nešķelt matus pārāk ilgi un nekavējoties atbildēt sev uz galvenajiem jautājumiem:

  • Kādi minimālie dati ir jānosūta serverim, lai abonentam varētu nosūtīt SMS īsziņu?
  • Kādi minimālie dati ir jānosūta no servera, lai apmierinātu klienta vajadzības?

Kaut kas man saka, ka šim nolūkam ir jānosūta:

  • mobilā tālruņa numuru un
  • SMS ziņas tekstu.

Principā ar šiem diviem raksturlielumiem pietiek, lai nosūtītu, bet es uzreiz iztēlojos gadījumu, kad sms ar dzimšanas dienas apsveikumiem pienāk 3 vai 4 no rīta! Šajā brīdī būšu ļoti pateicīgs visiem, ka neaizmirsa par mani! Tāpēc arī nosūtīsim uz serveri un

  • SMS ziņas nosūtīšanas datums.

Nākamā lieta, ko es vēlētos nosūtīt serverim, ir:

  • Ziņojuma veids.

Šis parametrs nav obligāts, taču tas mums var būt ļoti noderīgs, ja mums ātri jāpasaka priekšniekam, cik klientu esam “iepriecinājuši” ar saviem jaunumiem, kā arī uzzīmējam skaistu statistiku par šo lietu.

Un tomēr es kaut ko aizmirsu! Ja mēs pārdomājam nedaudz vairāk, ir vērts atzīmēt, ka klients vienlaikus var nosūtīt serverim vai nu vienu SMS īsziņu, vai vairākas tās. Citiem vārdiem sakot, viena datu pakete var saturēt no viena līdz bezgalībai ziņojumiem.

Rezultātā mēs saņemam, ka, lai nosūtītu īsziņu, mums ir nepieciešami šādi dati:

  • Mobilā tālruņa numurs,
  • SMS ziņas teksts,
  • īsziņas nosūtīšanas laiks abonentam,
  • ziņojuma veids.

Mēs esam atbildējuši uz pirmo jautājumu, tagad mums ir jāatbild uz otro jautājumu. Un varbūt es atļaušos nedaudz pajukt. Tāpēc no servera mēs nosūtīsim tikai Būla datus, kuru nozīmei ir šāda nozīme:

  • TRUE – pakete veiksmīgi sasniegusi serveri, izturējusi autentifikāciju un ievietota rindā nosūtīšanai SMS pakalpojumu sniedzējam
  • FALSE – visos citos gadījumos

Ar to problēmas izklāsta apraksts ir noslēdzies! Un visbeidzot, ķersimies pie jautrības – izdomāsim, kas par dīvainu zvēru ir šīs ZIEPES!

2 Kas ir SOAP?

Vispār, sākotnēji es neplānoju neko rakstīt par to, kas ir SOAP un gribēju aprobežoties ar saitēm uz w3.org vietni ar nepieciešamajām specifikācijām, kā arī saitēm uz Vikipēdiju. Bet pašās beigās nolēmu uzrakstīt īsu piezīmi par šo protokolu.

Un es sākšu savu stāstu ar to, ka šis datu apmaiņas protokols pieder protokolu apakškopai, kuras pamatā ir tā sauktā RPC (Remote Procedure Call) paradigma, kuras antipods ir REST (Representational State Transfer). Vairāk par to varat lasīt Vikipēdijā; saites uz rakstiem ir tēmas pašās beigās. No šiem rakstiem mums ir jāsaprot sekojošais: “RPC pieeja ļauj izmantot nelielu skaitu tīkla resursu ar lielu skaitu metožu un sarežģītu protokolu. Izmantojot REST pieeju, metožu skaits un protokolu sarežģītība ir stingri ierobežota, kas nozīmē, ka atsevišķu resursu skaits var būt liels. Tas nozīmē, ka attiecībā uz mums tas nozīmē, ka vietnē RPC pieejas gadījumā vienmēr būs viena ievade (saite) uz pakalpojumu un kāda procedūra izsaukt, lai apstrādātu ienākošos datus, ko mēs pārsūtām kopā ar datiem, savukārt ar REST pieeju mūsu Vietnē ir daudz ievades (saišu), no kurām katra pieņem un apstrādā tikai noteiktus datus. Ja kāds, kas lasa, zina, kā vēl vienkāršāk izskaidrot šo pieeju atšķirību, noteikti rakstiet komentāros!

Nākamā lieta, kas mums jāzina par SOAP, ir tāda, ka šis protokols izmanto to pašu XML kā transportu, kas, no vienas puses, ir ļoti labs, jo Mūsu arsenālā uzreiz ir iekļauts pilns tehnoloģiju kaudzes spēks, kas balstīts uz šo iezīmēšanas valodu, proti, XML-Schema - valoda XML dokumenta struktūras aprakstīšanai (paldies Wikipedia!), kas ļauj automātiski pārbaudīt servera saņemtos datus. no klientiem.

Tātad, tagad mēs zinām, ka SOAP ir protokols, ko izmanto attālo procedūru izsaukumu ieviešanai, un tas izmanto XML kā transportu! Izlasot rakstu Wikipedia, no turienes varat arī uzzināt, ka to var izmantot jebkurā lietojumprogrammas līmeņa protokolā, nevis tikai kopā ar HTTP (diemžēl šajā tēmā mēs apskatīsim tikai SOAP, izmantojot HTTP). Un zini, kas man šajā visā patīk visvairāk? Ja nav minējumu, tad došu mājienu - ZIEPES!... Joprojām nav minējumu?... Vai esat pārliecināts, ka esat izlasījis rakstu Vikipēdijā?... Vispār, es jūs vairs nespīdināšu. Tāpēc es ķeršos tieši pie atbildes: “SOAP (no angļu valodas vienkāršās objektu piekļuves protokola — vienkārši protokols piekļuve objektiem; līdz specifikācijai 1.2)". Visievērojamākais šajā rindā ir slīprakstā! Nezinu, kādus secinājumus jūs no tā visa izdarījāt, bet es redzu sekojošo - tā kā šo protokolu nekādi nevar saukt par “vienkāršu” (un acīmredzot pat w3 tam piekrīt), tad no 1.2 versijas tas pārstāja kaut kā atšifrēt ! Un tas kļuva pazīstams kā SOAP, tikai SOAP, punkts.

Nu, labi, lūdzu, atvainojiet, mēs to paņēmām mazliet malā. Kā jau rakstīju iepriekš, XML tiek izmantots kā transports, un paketes, kas pārvietojas starp klientu un serveri, sauc par SOAP aploksnēm. Ja ņem vērā aploksnes vispārējo struktūru, tā tev šķitīs ļoti pazīstama, jo... atgādina HTML lapas marķējumu. Tam ir galvenā sadaļa - Apvelciet, kas ietver sadaļas Virsraksts Un Ķermenis, vai Vaina. IN Ķermenis dati tiek pārsūtīti un tā ir obligāta aploksnes sadaļa, kamēr Virsraksts nav obligāta. IN Virsraksts var tikt pārsūtīta autorizācija vai jebkādi citi dati, kas nav tieši saistīti ar tīmekļa pakalpojuma procedūru ievades datiem. Par Vaina nekas īpašs nav ko stāstīt, izņemot to, ka tas pienāk klientam no servera, ja rodas kādas kļūdas.

Šeit beidzas mans apskatu stāsts par SOAP protokolu (pašas aploksnes un to struktūru apskatīsim sīkāk, kad beidzot mūsu klients un serveris iemācīsies tos palaist viens pie otra) un sākas jauns - par SOAP kompanjonu ar nosaukumu SOAP. WSDL(Web Services Description Language). Jā, jā, tas ir tas, kas atbaida lielāko daļu no mums pat no mēģinājumiem ieviest mūsu API šajā protokolā. Tā rezultātā mēs parasti izgudrojam savu riteni no jauna, izmantojot JSON kā transportu. Tātad, kas ir WSDL? WSDL ir valoda tīmekļa pakalpojumu aprakstīšanai un piekļuvei tiem, pamatojoties uz XML valodu (c) Wikipedia. Ja šī definīcija jums neizskaidro visu šīs tehnoloģijas sakrālo nozīmi, tad es mēģināšu to aprakstīt saviem vārdiem!

WSDL ir paredzēts, lai ļautu mūsu klientiem normāli sazināties ar serveri. Lai to izdarītu, failā ar paplašinājumu “*.wsdl” ir aprakstīta šāda informācija:

  • Kādas nosaukumvietas tika izmantotas?
  • Kādas datu shēmas tika izmantotas?
  • Kāda veida ziņojumus tīmekļa pakalpojums sagaida no klientiem?
  • Kuri dati pieder kādām tīmekļa pakalpojumu procedūrām,
  • Kādas procedūras ietver tīmekļa pakalpojums?
  • Kā klientam vajadzētu izsaukt tīmekļa pakalpojumu procedūras,
  • Uz kuru adresi jāsūta klientu zvani?

Kā redzat, šis fails ir viss tīmekļa pakalpojums. Klientā norādot WSDL faila adresi, mēs uzzināsim visu par jebkuru tīmekļa pakalpojumu! Tā rezultātā mums nav jāzina pilnīgi nekas par to, kur atrodas pats tīmekļa pakalpojums. Viss, kas jums jāzina, ir tā WSDL faila atrašanās vieta! Mēs drīz uzzināsim, ka SOAP nav tik biedējoša, kā to dara krievu sakāmvārdi.

3 Ievads XML shēmā

Tagad mēs zinām daudz par to, kas ir SOAP, kas tajā atrodas, un mums ir pārskats par tehnoloģiju kopumu, kas to ieskauj. Tā kā, pirmkārt, SOAP ir mijiedarbības metode starp klientu un serveri, un XML iezīmēšanas valoda tiek izmantota kā transports, šajā sadaļā mēs nedaudz sapratīsim, kā notiek automātiskā datu validācija, izmantojot XML shēmas.

Diagrammas galvenais uzdevums ir aprakstīt to datu struktūru, kurus mēs gatavojamies apstrādāt. Visi dati XML shēmās ir sadalīti vienkārši(skalārs) un komplekss(struktūru) veidi. Pie vienkāršiem veidiem pieder šādi veidi:

  • līnija,
  • numurs,
  • Būla vērtība,
  • datums.

Kaut kas ļoti vienkāršs, kam iekšā nav paplašinājumu. Viņu antipods ir sarežģīts komplekss tips. Vienkāršākais sarežģītā tipa piemērs, kas visiem ienāk prātā, ir objekti. Piemēram, grāmata. Grāmata sastāv no īpašībām: autors, Vārds, cena, ISBN numurs utt. Un šīs īpašības, savukārt, var būt gan vienkāršas, gan sarežģītas. Un XML shēmas uzdevums ir to aprakstīt.

Iesaku nekur tālu neiet un uzrakstīt XML shēmu mūsu SMS ziņai! Zemāk ir īsziņas xml apraksts:

71239876543 Testa ziņojums 2013-07-20T12:00:00 12

Mūsu sarežģītā tipa diagramma izskatīsies šādi:

Šis ieraksts skan šādi: Mums ir mainīgais " ziņa"tips" Ziņojums un ir sarežģīts veids, ko sauc par Ziņojums", kas sastāv no secīgas elementu kopas" tālrunis"tips virkne, « tekstu"tips virkne, « datums"tips datums Laiks, « veids"tips decimālzīme. Šie veidi ir vienkārši un jau ir definēti shēmas aprakstā. Apsveicam! Mēs tikko uzrakstījām savu pirmo XML shēmu!

Es domāju, ka elementu nozīme " elements" Un " komplekssTips"Jums viss ir kļuvis vairāk vai mazāk skaidrs, tāpēc mēs vairs nekoncentrēsimies uz tiem un pāriesim tieši uz komponista elementu." secība" Kad mēs izmantojam komponista elementu " secība“Informējam, ka tajā iekļautajiem elementiem vienmēr jāatrodas diagrammā norādītajā secībā, un tie visi ir obligāti. Bet nevajag izmisumā! XML shēmās ir vēl divi komponista elementi: " izvēle" Un " visi" Komponists" izvēle" paziņo, ka ir jābūt vienam no tajā uzskaitītajiem elementiem, un komponists " visi» – jebkura uzskaitīto elementu kombinācija.

Kā atceraties, pirmajā tēmas sadaļā vienojāmies, ka no viena līdz bezgalībai SMS ziņas var pārsūtīt pakā. Tāpēc es ierosinu saprast, kā šādi dati tiek deklarēti XML shēmā. Vispārējā pakotnes struktūra varētu izskatīties šādi:

71239876543 Testa ziņojums 1 2013-07-20T12:00:00 12 71239876543 Testa ziņojums N 2013-07-20T12:00:00 12

Šāda sarežģīta tipa diagramma izskatīsies šādi:

Pirmajā blokā ir pazīstama kompleksā tipa deklarācija “ Ziņojums" Ja pamanījāt, tad katrā vienkāršajā veidā, kas iekļauts " Ziņojums", ir pievienoti jauni precizējoši atribūti" minNotiek" Un " maxNotiek" Kā jūs varētu nojaust pēc nosaukuma, pirmais ( minNotiek) norāda, ka šajā secībā ir jābūt vismaz vienam elementam, kura tips ir “ tālrunis», « tekstu», « datums" Un " veids", savukārt nākamais ( maxNotiek) atribūts mums paziņo, ka mūsu secībā ir ne vairāk kā viens šāds elements. Rezultātā, rakstot savas shēmas jebkuriem datiem, mums tiek dota visplašākā izvēle, kā tās konfigurēt!

Otrais diagrammas bloks deklarē elementu " ziņojumu saraksts"tips" Ziņojumu saraksts" Ir skaidrs, ka" Ziņojumu saraksts"ir sarežģīts tips, kas satur vismaz vienu elementu" ziņa", taču maksimālais šādu elementu skaits nav ierobežots!

4 Uzrakstiet savu WSDL

Vai atceraties, ka WSDL ir mūsu tīmekļa pakalpojums? Ceru, ka atceries! Kamēr mēs to rakstīsim, tajā darbosies mūsu mazais tīmekļa pakalpojums. Tāpēc iesaku nejaukties.

Kopumā, lai mums viss darbotos pareizi, mums ir jāpārsūta klientam WSDL fails ar pareizo MIME tipu. Lai to izdarītu, jums ir attiecīgi jākonfigurē tīmekļa serveris, proti, iestatiet MIME veidu failiem ar paplašinājumu “*.wsdl” uz šādu rindu:

Lietojumprogramma/wsdl+xml

Bet praksē es parasti nosūtīju HTTP galveni caur PHP " teksts/xml»:

Header("Satura veids: text/xml; charset=utf-8");

un viss strādāja lieliski!

Uzreiz gribu brīdināt, ka mūsu vienkāršajam tīmekļa pakalpojumam būs diezgan iespaidīgs apraksts, tāpēc nebaidieties, jo... Lielākā daļa teksta ir obligāts ūdens, un, vienu reizi to uzrakstījis, jūs varat pastāvīgi kopēt no viena tīmekļa servisa uz otru!

Tā kā WSDL ir XML, jums par to jāraksta tieši pašā pirmajā rindā. Faila saknes elementam vienmēr jābūt sauktam " definīcijas»:

Parasti WSDL sastāv no 4-5 galvenajiem blokiem. Pats pirmais bloks ir tīmekļa pakalpojuma definīcija vai, citiem vārdiem sakot, ieejas punkts.

Šeit teikts, ka mums ir pakalpojums, ko sauc - " SmsService" Principā visus nosaukumus WSDL failā jūs varat mainīt uz tiem, ko vēlaties, jo viņi nespēlē absolūti nekādu lomu.

Pēc tam paziņojam, ka mūsu interneta pakalpojumā " SmsService" ir ieejas punkts ("ports") ar nosaukumu " SmsServicePort" Tieši uz šo ieejas punktu tiks nosūtīti visi pieprasījumi no klientiem uz serveri. Un norādiet elementā " adrese» saite uz apstrādātāja failu, kas pieņems pieprasījumus.

Kad esam definējuši tīmekļa pakalpojumu un norādījuši tā ieejas punktu, mums ar to jāsaista atbalstītās procedūras:

Lai to izdarītu, tajā ir norādīts, kuras darbības un kādā formā tās tiks izsauktas. Tie. ostai " SmsServicePort"iesiešana ir definēta zem nosaukuma" SmsServiceBinding", kam ir zvana veids" Rpc"un HTTP tiek izmantots kā pārraides protokols. Tādējādi mēs šeit norādījām, ka veiksim RPC zvanu, izmantojot HTTP. Pēc tam mēs aprakstām, kuras procedūras ( darbība) tiek atbalstīti tīmekļa pakalpojumā. Mēs atbalstīsim tikai vienu procedūru – “ nosūtīt SMS" Izmantojot šo procedūru, mūsu brīnišķīgās ziņas tiks nosūtītas uz serveri! Pēc procedūras deklarēšanas ir jānorāda, kādā formā dati tiks pārsūtīti. Šajā gadījumā tiek norādīts, ka tiks izmantotas standarta SOAP aploksnes.

Pēc tam mums ir jāsaista procedūra ar ziņojumiem:

Lai to izdarītu, mēs norādām, ka mūsu saistīšanas veids ir " SmsServicePortType" un elementā " porta tips"ar tāda paša veida nosaukumu mēs norādām procedūru piesaisti ziņojumiem. Tātad ienākošais ziņojums (no klienta uz serveri) tiks saukts par " nosūtītSmsRequest", un izejošie (no servera uz klientu)" sendSmsResponse" Tāpat kā visi WSDL nosaukumi, ienākošo un izejošo ziņojumu nosaukumi ir patvaļīgi.

Tagad jāapraksta paši ziņojumi, t.i. ienākošie un izejošie:

Lai to izdarītu, mēs pievienojam elementus " ziņa"ar vārdiem" nosūtītSmsRequest" Un " sendSmsResponse"attiecīgi. Tajos mēs norādām, ka ievadei jābūt aploksnei, kuras struktūra atbilst datu tipam " Pieprasīt" Pēc tam no servera tiek atgriezta aploksne, kurā ir datu tips - " Atbilde».

Tagad mums ir jādara tikai nedaudz - pievienojiet šo tipu aprakstu mūsu WSDL failam! Un kā, jūsuprāt, WSDL apraksta ienākošos un izejošos datus? Domāju, ka tu jau sen visu esi sapratis un sev teicis, ka izmantojot XML shēmas! Un jums būs pilnīga taisnība!

Jūs varat mūs apsveikt! Mūsu pirmais WSDL ir uzrakstīts! Un esam soli tuvāk sava mērķa sasniegšanai.
Tālāk mēs apskatīsim, ko PHP mums nodrošina mūsu pašu izplatīto lietojumprogrammu izstrādei.

5 Mūsu pirmais SOAP serveris

Iepriekš rakstīju, ka SOAP servera izveidošanai PHP izmantosim iebūvēto SoapServer klasi. Lai visas turpmākās darbības notiktu tāpat kā man, jums būs nedaudz jāpielāgo jūsu PHP. Lai būtu vēl precīzāk, jums ir jāpārliecinās, vai ir instalēts paplašinājums “php-soap”. Vislabāk ir izlasīt, kā to instalēt savā tīmekļa serverī oficiālajā PHP vietnē (skatiet atsauču sarakstu).

Kad viss ir instalēts un konfigurēts, mums būs jāizveido fails jūsu mitināšanas saknes mapē " smsservice.php» ar šādu saturu:

setClass("SoapSmsGateWay"); //Sākt serveri $server->handle();

Es ceru, ka nav nepieciešams paskaidrot, kas atrodas virs līnijas ar funkciju “ini_set”. Jo tur tiek noteikts, kuras HTTP galvenes mēs nosūtīsim no servera klientam un tiek konfigurēta vide. Rindā ar “ini_set” mēs atspējojam WSDL faila kešatmiņu, lai mūsu izmaiņas tajā nekavējoties stātos spēkā klientam.

Tagad mēs nonākam pie servera! Kā redzat, viss SOAP serveris aizņem tikai trīs rindas! Pirmajā rindā mēs izveidojam jaunu SoapServer objekta gadījumu un nododam tīmekļa pakalpojuma WSDL apraksta adresi tā konstruktoram. Tagad mēs zinām, ka tas atradīsies mitināšanas saknē failā ar pašsaprotamu nosaukumu “ smsservice.wsdl.php" Otrajā rindā mēs sakām SOAP serverim, kura klase ir jāizvelk, lai apstrādātu no klienta saņemto aploksni un atgrieztu aploksni ar atbildi. Kā jūs varētu uzminēt, šajā klasē tiks aprakstīta mūsu vienīgā metode nosūtīt SMS. Trešajā rindā mēs sākam serveri! Tas arī viss, mūsu serveris ir gatavs! Ar ko es mūs visus apsveicu!

Tagad mums ir jāizveido WSDL fails. Lai to izdarītu, varat vai nu vienkārši kopēt tās saturu no iepriekšējās sadaļas, vai arī uzņemties brīvību un nedaudz "veidot" to:

"; ?> /" 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" />

Šajā posmā mums vajadzētu būt pilnībā apmierinātiem ar iegūto serveri, jo Mēs varam reģistrēt pienākošās aploksnes un tad mierīgi analizēt ienākošos datus. Lai mēs varētu kaut ko saņemt serverī, mums ir nepieciešams klients. Tātad ķersimies pie tā!

6 SOAP klients ceļā

Pirmkārt, mums ir jāizveido fails, kurā mēs ierakstīsim klientu. Kā parasti, mēs to izveidosim saimniekdatora saknē un sauksim to " klients.php", un iekšpusē mēs rakstīsim sekojošo:

messageList = new MessageList(); $pieprasījums->ziņojumu saraksts->ziņa = jauns ziņojums(); $req->messageList->message->phone = "79871234567"; $req->messageList->message->text = "Pārbaudes ziņojums 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->message->type = 15; $klients = new SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php, array("ziepju_versija" => SOAP_1_2)); var_dump($klients->sūtītSms($req));

Aprakstīsim savus objektus. Kad mēs rakstījām WSDL, tas aprakstīja trīs entītijas aploksnei, kas ienāk serverī: Pieprasīt, Ziņojumu saraksts Un Ziņojums. Attiecīgi klases Pieprasīt, Ziņojumu saraksts Un Ziņojums ir šo entītiju atspoguļojums mūsu PHP skriptā.

Kad esam definējuši objektus, mums ir jāizveido objekts ( $piepras), ko mēs nosūtīsim uz serveri. Pēc tam nāk divas mums lolotākās līnijas! Mūsu SOAP klients! Tici vai nē, bet ar to pietiek, lai mūsu serveris sāktu saņemt ziņas no klienta, kā arī lai mūsu serveris tās veiksmīgi saņemtu un apstrādātu! Pirmajā no tiem mēs izveidojam SoapClient klases instanci un nododam WSDL faila atrašanās vietas adresi tā konstruktoram, un parametros skaidri norādām, ka strādāsim, izmantojot SOAP protokola versiju 1.2. Nākamajā rindā mēs saucam metodi nosūtīt SMS objektu $klients un nekavējoties parādiet rezultātu pārlūkprogrammā.
Palaidīsim to un redzēsim, ko mēs beidzot ieguvām!

No servera man tika atgriezts šāds objekts:

Objekta(stdClass) publiskais "statuss" => Būla patiess

Un tas ir lieliski, jo... Tagad mēs noteikti zinām, ka mūsu serveris darbojas un ne tikai darbojas, bet arī var atgriezt klientam dažas vērtības!

Tagad apskatīsim žurnālu, ko apdomīgi glabājam servera pusē! Pirmajā daļā mēs redzam neapstrādātus datus, kas ieradās serverī:

79871234567 Testa ziņojums 1 2013-07-21T15:00:00.26 15

Šī ir aploksne. Tagad jūs zināt, kā tas izskatās! Bet maz ticams, ka mēs būsim ieinteresēti to aplūkot visu laiku, tāpēc deserializēsim objektu no žurnālfaila un pārbaudīsim, vai viss ir kārtībā:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => string "79871234567" (garums=11) public "text" => string "Test message 1 " (garums=37) publiskais "datums" => virkne "2013-07-21T15:00:00.26" (garums=22) publiskais "tips" => virkne "15" (garums=2)

Kā redzat, objekts tika deserializēts pareizi, ar ko vēlos mūs visus apsveikt! Tālāk mūs sagaida kaut kas interesantāks! Proti, nosūtīsim klientam uz serveri ne tikai vienu SMS īsziņu, bet veselu paku (precīzāk, trīs)!

7 Sarežģītu objektu sūtīšana

Padomāsim, kā vienā paketē uz serveri var pārsūtīt veselu kaudzi ziņojumu? Iespējams, vienkāršākais veids būtu organizēt masīvu elementā messageList! Darām to:

// izveidot objektu, ko nosūtīt uz serveri $req = new Request(); $pieprasījums->ziņojumu saraksts = new MessageList(); $msg1 = jauns ziņojums(); $msg1->phone = "79871234567"; $msg1->text = "Pārbaudes ziņojums 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->tips = 15; $msg2 = jauns ziņojums(); $msg2->phone = "79871234567"; $msg2->text = "Pārbaudes ziņojums 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->tips = 16; $msg3 = jauns ziņojums(); $msg3->phone = "79871234567"; $msg3->text = "Pārbaudes ziņojums 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->tips = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $msg3;

Mūsu žurnāli norāda, ka no klienta tika saņemta šāda pakete:

79871234567 Testa ziņojums 1 2013-07-21T15:00:00.26 15 79871234567 Testa ziņojums 2 2014-08-22T16:01:10 16 79871234567 Testa ziņojums 3 2014-08-22T16:01:10 17

Kādas muļķības, tu saki? Un savā ziņā tev būs taisnība, jo... Tiklīdz uzzinājām, ka kāds objekts pametis klientu, tas nonāca mūsu serverī absolūti tādā pašā veidā aploksnes veidā. Tiesa, SMS ziņas netika serializētas XML formātā mums vajadzīgajā veidā – tās bija jāiepako elementos ziņa, nav iekšā Struktūra. Tagad redzēsim, kādā formā šāds objekts nonāk pie metodes nosūtīt SMS:

Object(stdClass) public "messageList" => objekts(stdClass) public "message" => objekts(stdClass) public "Struct" => masīvs (izmērs=3) 0 => objekts(stdClass) publisks "tālrunis" => virkne "79871234567" (garums=11) publisks "text" => virkne "Pārbaudes ziņojums 1" (garums=37) publisks "datums" => virkne "2013-07-21T15:00:00.26" (garums=22) publisks " tips" => virkne "15" (garums=2) 1 => objekts(stdClass) publisks "tālrunis" => virkne "79871234567" (garums=11) publisks "teksts" => virkne "Test message 2" (garums= 37) publisks "datums" => virkne "2014-08-22T16:01:10" (garums=19) publiskais "tips" => virkne "16" (garums=2) 2 => objekts(stdClass) publisks "tālrunis " => virkne "79871234567" (garums=11) publisks "teksts" => virkne "Test message 3" (garums=37) publisks "datums" => virkne "2014-08-22T16:01:10" (garums= 19) publiskais "tips" => virkne "17" (garums = 2)

Ko šīs zināšanas mums dod? Tikai tas, ka izvēlētais ceļš nav pareizs un nesaņēmām atbildi uz jautājumu “Kā mēs varam iegūt pareizo datu struktūru serverī?” Bet es iesaku nekrist izmisumā un mēģināt pārvērst mūsu masīvu uz tipu objekts:

$req->messageList->message = (objekts)$req->messageList->message;

Šajā gadījumā mēs saņemsim citu aploksni:

79871234567 Testa ziņojums 1 2013-07-21T15:00:00.26 15 79871234567 Testa ziņojums 2 2014-08-22T16:01:10 16 79871234567 Testa ziņojums 3 2014-08-22T16:01:10 17

Ienāca metodē nosūtīt SMS objektam ir šāda struktūra:

Objekts(stdClass) publisks "messageList" => objekts(stdClass) publisks "ziņojums" => objekts(stdClass) publisks "BOGUS" => masīvs (izmērs=3) 0 => objekts(stdClass) publiskais "tālrunis" => virkne "79871234567" (garums=11) publisks "text" => virkne "Pārbaudes ziņojums 1" (garums=37) publisks "datums" => virkne "2013-07-21T15:00:00.26" (garums=22) publisks " tips" => virkne "15" (garums=2) 1 => objekts(stdClass) publisks "tālrunis" => virkne "79871234567" (garums=11) publisks "teksts" => virkne "Test message 2" (garums= 37) publisks "datums" => virkne "2014-08-22T16:01:10" (garums=19) publiskais "tips" => virkne "16" (garums=2) 2 => objekts(stdClass) publisks "tālrunis " => virkne "79871234567" (garums=11) publisks "teksts" => virkne "Test message 3" (garums=37) publisks "datums" => virkne "2014-08-22T16:01:10" (garums= 19) publiskais "tips" => virkne "17" (garums = 2)

Kas attiecas uz mani, “summa nemainās, mainot terminu vietas” (c). Kas BOGUS, Kas Struktūra– mēs vēl neesam sasnieguši savu mērķi! Un, lai to panāktu, mums ir jāpārliecinās, ka šo nesaprotamo vārdu vietā tiek parādīts mūsu dzimtais ziņa. Bet autors vēl nezina, kā to panākt. Tāpēc vienīgais, ko varam darīt, ir atbrīvoties no papildu konteinera. Citiem vārdiem sakot, mēs tagad pārliecināsimies, ka tā vietā ziņa kļuva BOGUS! Lai to izdarītu, mainiet objektu šādi:

// izveidot objektu, ko nosūtīt uz serveri $req = new Request(); $msg1 = jauns ziņojums(); $msg1->phone = "79871234567"; $msg1->text = "Pārbaudes ziņojums 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->tips = 15; $msg2 = jauns ziņojums(); $msg2->phone = "79871234567"; $msg2->text = "Pārbaudes ziņojums 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->tips = 16; $msg3 = jauns ziņojums(); $msg3->phone = "79871234567"; $msg3->text = "Pārbaudes ziņojums 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->tips = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (objekts)$req->messageList;

Ko darīt, ja mums paveicas un diagrammā parādās pareizais nosaukums? Lai to izdarītu, apskatīsim saņemto aploksni:

79871234567 Testa ziņojums 1 2013-07-21T15:00:00.26 15 79871234567 Testa ziņojums 2 2014-08-22T16:01:10 16 79871234567 Testa ziņojums 3 2014-08-22T16:01:10 17

Jā, brīnums nenotika! BOGUS- mēs neuzvarēsim! Ieradās nosūtīt SMS objekts šajā gadījumā izskatīsies šādi:

Object(stdClass) public "messageList" => objekts(stdClass) public "BOGUS" => masīvs (izmērs=3) 0 => objekts(stdClass) publisks "tālrunis" => virkne "79871234567" (garums=11) publisks " text" => string "Pārbaudes ziņojums 1" (garums=37) publisks "datums" => virkne "2013-07-21T15:00:00.26" (garums=22) publisks "tips" => virkne "15" (garums) =2) 1 => objekts(stdClass) publiskais "tālrunis" => virkne "79871234567" (garums=11) publiskais "teksts" => virkne "Pārbaudes ziņojums 2" (garums=37) publiskais "datums" => virkne " 2014-08-22T16:01:10" (garums=19) publisks "tips" => virkne "16" (garums=2) 2 => objekts(stdClass) publisks "tālrunis" => virkne "79871234567" (garums= 11) public "text" => string "Test message 3" (garums=37) public "date" => string "2014-08-22T16:01:10" (garums = 19) public "type" => string " 17" (garums = 2)

Kā saka - "Gandrīz"! Uz šīs (nedaudz skumjās) nots es ierosinu lēnām iesākt lietas un izdarīt dažus secinājumus.

8 Secinājums

Beidzot esam klāt! Izdomāsim, ko jūs varat darīt tagad:

  • varat uzrakstīt savam tīmekļa pakalpojumam nepieciešamo WSDL failu;
  • jūs varat viegli uzrakstīt savu klientu, kas var sazināties ar serveri, izmantojot SOAP;
  • jūs varat uzrakstīt savu serveri, kas sazinās ar ārpasauli, izmantojot SOAP;
  • jūs varat nosūtīt tāda paša veida objektu masīvus uz serveri no sava klienta (ar dažiem ierobežojumiem).

Mūsu nelielā pētījuma laikā mēs arī izdarījām dažus atklājumus:

  • vietējā SoapClient klase nepareizi serializē viena veida datu struktūras XML;
  • serializējot masīvu uz XML, tas rada papildu elementu, ko sauc Struktūra;
  • serializējot objektu XML, tas izveido papildu elementu, ko sauc BOGUS;
  • BOGUS mazāk ļaunuma nekā Struktūra sakarā ar to, ka aploksne ir kompaktāka (aploksnes XML galvenē netiek pievienotas papildu nosaukumvietas);
  • Diemžēl klase SoapServer automātiski nepārbauda aploksnes datus ar mūsu XML shēmu (iespējams, arī citi serveri to nedara).

Šeit LeaseWeb mēs daudz strādājam ar SOAP tīmekļa pakalpojumiem, lai integrētu mūsu iekšējās lietojumprogrammas savā starpā. Īpaši mūsu lietojumprogrammu izstrādes un testēšanas laikā, jo mums ir nepieciešama iespēja praktizēt ar SOAP API.

$ curl -sS http://leaseweb.github.io/php-soap-client/installer | php

Tas lejupielādēs phar failu pašreizējā darba direktorijā un padarīs to izpildāmu, lai jūs varētu nekavējoties sākt to lietot, izsaucot:

$ ./ziepju_klients

Lai instalētu jaunāko galveno versiju, varat iegūt avota kodu tieši no GitHub, iepakot savu .phar failu un instalēt to, izmantojot GNU Make.
Lai varētu izveidot .phar failu, jums ir jābūt instalētam komponistam. Lai uzzinātu vairāk par komponistu, skatiet viņu lielisko dokumentāciju.

# Instalējiet php soap klientu $ git clone https://github.com/LeaseWeb/php-soap-client.git $ cd php-soap-client $ composer.phar instalēt $ make $ sudo make install

Ja darbības laikā tiek parādīts izņēmums Neizdevās kompilēt phar, savā php.ini ir jāiestata phar.readonly=Off. Izstrādes mašīnā tas ir labi, taču, lūdzu, ņemiet vērā drošības riskus, iestatot phar.readonly uz Off.

Iepriekš minētā make install komanda instalēs lietojumprogrammu soap_client mapē /usr/local/bin un padarīs to izpildāmu, lai jūs to varētu viegli izsaukt šādi:

$ soap_client php-soap-client versija 2.1.3 Lietojums: komanda Iespējas: ... Pieejamās komandas: izsaukt attālo pakalpojumu ar norādīto metodi un izvadīt atbildi uz stdout. help Parāda palīdzību komandu sarakstam Uzskaita komandas list-methods Iegūstiet pieejamo metožu sarakstu, lai izsauktu tālvadības pulti. pieprasījums Ģenerējiet xml formatētu SOAP pieprasījumu dotajai metodei un izvadiet to uz stdout. wsdl Iegūstiet ziepju pakalpojuma WSDL.

No šī brīža mēs pieņemam, ka esat instalējis soap_client.phar savā sistēmā mapē /usr/local/bin/soap_client un direktorijs /urs/local/bin atrodas jūsu $PATH .

Pieņemsim, ka mēs vēlētos redzēt, kādas metodes ir pieejamas attālajā pakalpojumā http://www.webservicex.net/ConvertTemperature.asmx. Mēs varētu izdot šādu komandu:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" list-methods

Kas izvadīs sekojošo:

ConvertTemp

Ja palaižat iepriekš minēto komandu ar opciju -vvv, jūs iegūsit detalizētāku izvadi.
Šajā gadījumā vienīgā pieejamā metode ir ConvertTemp. Apskatīsim, kā izskatās SOAP XML pieprasījums šai metodei:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" pieprasījums ConvertTemp 0

Ja vēlaties veikt SOAP pieprasījumu ConvertTemp metodei attālajā pakalpojumā, izmantojiet zvana apakškomandu:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" call --editor ConvertTemp

Ievērojiet opciju --editor pēc zvana apakškomandas. Ja izmantojat karodziņu --editor, soap_client atvērs jūsu vides mainīgajā $EDITOR norādīto redaktoru, lai jūs varētu modificēt pieprasījuma XML pirms tā nosūtīšanas.

Ja izsniedzat vienu un to pašu pieprasījumu vairākas reizes, varat saglabāt ziepju pieprasījumu kā vietējo XML failu un nosūtīt to soap_client izsaukuma komandas /dev/stdin:

# Iegūstiet pieprasījumu xml un saglabājiet to lokāli $ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" pieprasījums ConvertTemp > my_sample_request.xml # Tagad rediģējiet my_sample_request.xml # Tagad varat izsaukt ConvertTemp metode ar šo iepriekš sagatavoto pieprasījumu $ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" izsauciet ConvertTemp< my_sample_request.xml

Tā kā, izpētot attālo tīmekļa pakalpojumu, īsā laikā bieži atkārtosit soap_client komandas, varat ietaupīt laiku, iestatot vides mainīgo SOAPCLIENT_ENDPOINT, kas satur WSDL URL. Kad šis vides mainīgais ir iestatīts, varat izlaist komandrindas opciju --endpoint. Darīsim to tagad un izsauksim ConvertTemp metodi:

$ eksportēt SOAPCLIENT_ENDPOINT="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" $ soap_client call ConvertTemp< my_sample_request.xml

Es vēlējos uzzināt, cik 107,6 grādi pēc Fārenheita ir pēc Celsija, tāpēc mans my_sample_request.xml satur:

$ kaķis my_sample_request.xml 107.6 grāds pēc Fārenheita grāds pēc Celsija

$ soap_client zvanu ConvertTemp< my_sample_request.xml stdClass Object ( => 42)

Atbilde ir 42.

Ja atbildes drīzāk redzat XML formātā, varat izmantot komandrindas opciju --xml:

$ soap_client zvans --xml ConvertTemp< my_sample_request.xml 42

Šajā apmācībā ir jāsniedz pietiekami daudz informācijas, lai sāktu SOAP API izpēti, testēšanu un/vai izstrādi.
Nākamajā bloga ierakstā es turpināšu tēmu par php ziepju klientu. Pašlaik mēs strādājam pie .phar arhīva iesaiņošanas tīmeklim.

Es nepiekavēšos pie jautājuma, kas tas ir tīmekļa pakalpojumi un kāpēc tie ir vajadzīgi. Internetā ir daudz rakstu par šo tēmu. Es tikai mēģināšu īsi parādīt, cik vienkārši ir izveidot klientu jebkuram tīmekļa pakalpojumam PHP.

Iestatījumi

Lietošanai ZIEPES php ir jāpievieno SOAP modulis (iekļauts php5 izplatīšanā). Operētājsistēmā Windows tas tiek darīts vienkārši — jums ir jāpievieno (proti, jāpievieno, jo šī rindiņa nav tikai komentēta, bet arī trūkst) php.ini:
paplašinājums=php_soap.dll

Neaizmirstiet restartēt serveri, ja php ir instalēts kā modulis.


SOAP klienta izveide no WSDL dokumenta

SOAP klienta izveide parasti notiek līdz WSDL dokuments, kas ir XML dokuments noteiktā formātā, kas pilnībā apraksta konkrētu tīmekļa pakalpojumu. Sīkāku informāciju par WSDL skatiet W3C konsorcija vietnē http://www.w3.org/TR/2005/WD-wsdl20-soap11-binding-20050510/.

Galvenais, kas jums jāzina, lai izveidotu klientu tīmekļa pakalpojumam, ir zināt tā WSDL dokumenta URL.
Piemēram, ņemsim tīmekļa pakalpojumu "Valūtas maiņas kurss" no xmethods.com. Šī tīmekļa pakalpojuma adrese, kas ļauj saņemt valūtas maiņas kursus tiešsaistē, ir http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl.

Otrs svarīgais punkts ir tas, ka no tīmekļa pakalpojuma apraksta ir jāiegūst informācija par to, kādas metodes šis pakalpojums nodrošina un kādus parametrus mums vajadzētu nodot tam kā ievades vērtības (ļoti līdzīgi kā parastās PHP funkcijas vai klases izsaukšanai metode). Parasti šī informācija ir ietverta pakalpojuma aprakstā tās tīmekļa vietnē. Mūsu tīmekļa pakalpojums valūtas maiņas kursu iegūšanai nodrošina metodi getRate(), kurai kā argumenti tiek nodoti valūtu kodi.

Un visbeidzot, ir svarīgi zināt, ko sagaidīt kā atbildi: cik vērtību, kāda veida utt. To var iegūt arī no apraksta.
Rezultātā kods izrādās ļoti vienkāršs un kompakts, gandrīz elementārs:

// Izmantojot Web pakalpojumu
// "Valūtas maiņas kurss" no xmethods.com

// SOAP klienta izveide no WSDL dokumenta
$klients = jauns SoapClient("http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl");

// Nosūtiet SOAP pieprasījumu un saņemiet rezultātu
$rezultāts = $klients->getRate("mums", "Krievija");

Echo 'Pašreizējais dolāra kurss: ', $rezultāts, ' rubļi';
?>

Kā redzams no koda, jums ir jānodod WSDL dokumenta URL SoapClient klases konstruktoram un jāsaņem objekts darbam ar vēlamo tīmekļa pakalpojumu. Pēc tam tiek izsaukta šī objekta metode, kuras nosaukums ir tāds pats kā pašas tīmekļa pakalpojuma metodes nosaukums. Šī metode atgriež vēlamo rezultātu.

Tātad šis vienkāršais piemērs ilustrē SOAP klienta izveides principu tīmekļa pakalpojumiem PHP. Tomēr reālā lietojumprogrammā joprojām ir daudz kas jārūpējas, jo īpaši tas, ka, izsaucot tīmekļa pakalpojumu, tas var īslaicīgi nebūt pieejams vai parādīt kļūdu. Tas skaidri iesaka izmantot bloku mēģināt/noķert/iemest :)

Brets Maklalins Iļjas Čekmeņeva tulkojums

SOAP ir vienkāršais objektu piekļuves protokols. Ja jūs nekad neesat par to dzirdējuši, tad jums jādzīvo nekurienes vidū, tālu no civilizācijas. Tā ir kļuvusi par jaunāko modi tīmekļa programmēšanā un par tīmekļa pakalpojumu neatņemamu sastāvdaļu, kas ar tādu fanātismu tiek izmantota jaunākās paaudzes tīmekļa izstrādē. Ja esat dzirdējis par Microsoft .NET jeb vienādranga "revolūciju", tad esat dzirdējis par tehnoloģijām, kas balstās uz SOAP (pat ja jūs nezināt, kas tas ir). Nav viens, bet divi SOAP implementācijas no Apache un Microsoft, kurām MSDN atbalsta vietnē (http://msdn.microsoft.com/) ir veltītas tūkstošiem lapu.

Šajā rakstā es jums pastāstīšu, kas ir SOAP un kāpēc tā ir tik svarīga daļa tīmekļa programmēšanas paradigmas attīstībā. Tas palīdzēs jums izlaist pamatus un nekavējoties sākt darbu ar SOAP rīku komplektu. Pēc tam es sniegšu īsu pārskatu par esošajiem SOAP projektiem un iedziļināšos Apache ieviešanā. Šis raksts nav paredzēts, lai sniegtu pilnīgu priekšstatu par SOAP; mana grāmata Java un XML, 2. izdevums, aizpilda daudzas nepilnības. Grāmatā atradīsiet atbildes uz daudziem jautājumiem, kas radās pēc šī raksta izlasīšanas.

Ievads

Vispirms jums ir jāsaprot, kas ir SOAP. Pilnu (un diezgan garo) W3C atzinumu varat izlasīt vietnē http://www.w3.org/TR/SOAP. Tad, izdomājis un izmetis visu mizu, sapratīsi, ka SOAP ir tikai protokols. Tas ir vienkāršs protokols (nav jāraksta jauns, lai to izmantotu), kura pamatā ir doma, ka kādā brīdī izplatītajā arhitektūrā rodas nepieciešamība apmainīties ar informāciju. Turklāt sistēmām, kurās ir iespējama pārslodze un apstrādes procesu sarežģījumi, šis protokols ir ļoti izdevīgs, jo tas ir viegls un prasa minimālu resursu daudzumu. Visbeidzot, tas ļauj visas darbības veikt, izmantojot HTTP, kas ļauj apiet tādas sarežģītas lietas kā ugunsmūri un pasargāt sevi no klausīšanās, izmantojot ligzdas neticami daudzos portos. Galvenais, lai tu to apzinies, un viss pārējais ir detaļas.

Protams, jūs vēlētos zināt šīs detaļas, un es tās ignorēšu. SOAP specifikācijā ir trīs pamata komponenti: SOAP aploksne, šifrēšanas noteikumu kopums un mijiedarbības līdzeklis starp pieprasījumu un atbildi. Padomāsim par SOAP ziņojumu kā parastu vēstuli. Vai vēl atceries tās senās lietas aploksnēs ar pastmarku un adresi, kas rakstīta priekšpusē? Šī analoģija palīdzēs jums skaidrāk izprast SOAP kā "aploksnes" jēdzienu. Attēlā 12-1 ir attēloti SOAP procesi šīs analoģijas veidā.

Attēls 12-1. SOAP ziņojumu process

Paturiet prātā šo attēlu un apskatīsim trīs SOAP specifikācijas sastāvdaļas. Es īsi runāšu par katru no tiem, sniedzot piemērus, kas vislabāk atspoguļo šo koncepciju. Šīs trīs galvenās sastāvdaļas padara SOAP tik svarīgu un nozīmīgu. Kļūdu apstrāde, dažādu šifrēšanas atbalsts, parametru serializācija un fakts, ka SOAP vairumā gadījumu darbojas, izmantojot HTTP, padara to pievilcīgāku par citiem izplatīto protokolu risinājumiem. SOAP nodrošina augstu savietojamības pakāpi ar citām lietojumprogrammām, kuras es sīkāk aplūkoju savā grāmatā. Pagaidām es vēlos koncentrēties uz SOAP galvenajiem elementiem.

Aploksne

SOAP aploksne ir līdzīga parastai vēstuļu aploksnei. Tajā ir informācija par ziņojumu, kas tiks šifrēta galvenajā SOAP sadaļā, tostarp informācija par adresātu un sūtītāju, kā arī informācija par pašu ziņojumu. Piemēram, SOAP aploksnes galvene var norādīt, kā ziņojums ir jāapstrādā. Pirms lietojumprogramma sāk ziņojuma apstrādi, tā pārbauda informāciju par ziņojumu, tostarp to, vai tā vispār var apstrādāt ziņojumu. Atšķirībā no situācijas ar standarta XML-RPC izsaukumiem (atcerieties? XML-RPC ziņojumi, šifrēšana utt., viss tiek apvienots vienā XML fragmentā), ar SOAP notiek nepārtraukta apstrāde, lai kaut ko uzzinātu par ziņojumu. Tipisks SOAP ziņojums var ietvert arī šifrēšanas stilu, kas palīdzēs adresātam apstrādāt ziņojumu. Piemērā 12-1 ir parādīta SOAP aploksne, kas beidzas ar kodēšanas specifikāciju.

Piemērs 12-1: SOAP Aploksne

Ziepju kaste http://www-106.ibm.com/developerworks/library/x-soapbx1.html

Kā redzat, šifrēšana ir iestatīta aploksnes iekšpusē, kas ļauj lietojumprogrammai noteikt (izmantojot atribūta vērtību kodēšanas stils), vai tā var nolasīt ienākošo ziņojumu, kas atrodas elementā Ķermenis. Pārliecinieties, vai SOAP aploksnes nosaukumvieta ir pareiza, vai arī SOAP serveri, kas saņem jūsu ziņojumu, ziņos par versijas neatbilstības kļūdu, un jūs nevarēsit ar tiem sazināties.

Šifrēšana

Otrs svarīgais SOAP elements ir iespēja šifrēt pielāgotus datu tipus. Izmantojot RPC (un XML-RPC), šifrēšanu var veikt tikai iepriekš definētiem datu tipiem, kas tiek atbalstīti jūsu lejupielādētajā XML-RPC rīkkopā. Lai šifrētu cita veida datus, jums pašam jāmaina RPC serveris un klients. Izmantojot SOAP, XML shēmu var diezgan viegli izmantot, lai norādītu jaunus datu tipus (izmantojot struktūru komplekssTips, kas apspriests manas grāmatas 2. nodaļā), un šos jaunos veidus var attēlot XML kā daļu no SOAP galvenās sadaļas. Pateicoties XML shēmas integrācijai, jūs varat šifrēt jebkura veida datus SOAP ziņojumā, loģiski aprakstot tos XML shēmā.

Zvaniet

Labākais veids, kā saprast, kā darbojas SOAP zvans, ir salīdzināt to ar kaut ko jau pazīstamu, piemēram, XML-RPC. Ja atceraties, XML-RPC izsaukums izskatās līdzīgs koda fragmentam, kas parādīts 12-2. piemērā.

Piemērs 12-2. Zvaniet uz XML-RPC

// XML procesora (parsētāja) norādīšana, lai izmantotu XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser"); // Servera, ar kuru tiek izveidots savienojums, norādīšana XmlRpcClient client = new XmlRpcClient("http://rpc.middleearth.com"); // Parametru izveide Vector params = new Vector(); params.addElement(lidojuma numurs); params.addElement(sēdvietu skaits); params.addElement(kredītkartes veids); params.addElement(kredītkartesNumurs); // Pieprasīt Būla nopirktasTickets = (Boolean)client.execute("ticketCounter.buyTickets", params); // Apstrādājiet atbildi

Izveidoju vienkāršu programmu aviobiļešu pasūtīšanai. Tagad apskatiet piemēru 12-3, kas parāda SOAP zvanu.

Piemērs 12-3. Zvaniet uz SOAP

// Parametru izveide Vector params = new Vector(); params.addElement(new Parameter("lidojuma numurs", vesels skaitlis.klase, lidojuma numurs, null)); params.addElement(new Parameter("sēdvietu skaits", Integer.class, numSeats, null)); params.addElement(new Parameter("kredītkartes veids", String.class, creditCardType, null)); params.addElement(new Parameter("kredītkartesNumurs", Long.class, creditCardNum, null)); // Zvana objekta izveide Call call = new Call(); call.setTargetObjectURI("urn:xmltoday-airline-tickets"); call.setMethodName("pirkt Biļetes"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); call.setParams(params); // Call Response res = call.invoke(new URL("http://rpc.middleearth.com"), ""); // Apstrādājiet atbildi

Kā redzat, faktiskais zvans, ko pārstāv objekts Zvaniet, atmiņas iemītnieks. Tas ļauj norādīt zvana mērķi, zvana metodi, šifrēšanas stilu, parametrus un daudzus citus parametrus, kas nav parādīti šajā piemērā. Tas ir elastīgāks mehānisms nekā XML-RPC metode, kas ļauj skaidri norādīt dažādu parametru kopu, kas ir netieši definēti XML-RPC. Vēlāk šajā rakstā uzzināsit vairāk par zvanu procesu, tostarp to, kā SOAP apstrādā nederīgus pieprasījumus, kļūdu hierarhiju un, protams, atgrieztos zvanu rezultātus.

Pēc tik īsa ievada jūs jau zināt pietiekami daudz, lai interesētos par šo smieklīgo lietu. Tagad ļaujiet man jūs iepazīstināt ar SOAP ieviešanu, kuru es izmantošu. Es paskaidrošu iemeslus, kāpēc es to izvēlējos, un apskatīšu dažus kodu piemērus.

Iestatījumi

Tagad, kad esat apguvis koncepcijas pamatus, ir pienācis laiks jautrajai daļai: programmēšanai. Lai to izdarītu, jums būs nepieciešams ērts projekts vai produkts, kuru ir vieglāk atrast, nekā varētu šķist no pirmā acu uzmetiena. Ja jums ir nepieciešams Java projekts, kas nodrošina SOAP iespējas, jums nav ilgi jāmeklē, lai to atrastu. Ir divas produktu grupas: komerciāla un bezmaksas. Tāpat kā savā grāmatā, es izvairīšos pieminēt komerciālus produktus. Tas nepavisam nav tāpēc, ka tie ir slikti (tieši otrādi, daži no tiem ir izcili), bet gan tāpēc, ka es vēlētos, lai ikviens lasītājs varētu izmēģināt kādu no sniegtajiem piemēriem. Tas ir saistīts ar pieejamību, kuras daudziem komerciāliem produktiem nav. Lai tos izmantotu, jums ir jāmaksā vai uz laiku pēc lejupielādes tie jāizmanto ierobežotā laika periodā.

Tādējādi mēs raiti tuvojāmies atvērtā pirmkoda projektiem. No šīs jomas es varu nosaukt tikai vienu produktu: Apache SOAP. Tas atrodas vietnē http://xml.apache.org/soap un nodrošina SOAP rīkkopu Java. Rakstīšanas laikā tika izlaista versija 2.2, kuru varat lejupielādēt no Apache vietnes. Tieši šo versiju es izmantošu šī raksta piemēros.

Citas alternatīvas

Pirms pāriet uz Apache SOAP instalēšanu un konfigurēšanu, es atbildēšu uz dažiem jautājumiem, kas varētu būt iezagušies jūsu prātā. Es domāju, ka esmu diezgan skaidri izskaidrojis iemeslus, kāpēc es neizmantoju komerciālus produktus. Tomēr jūs, iespējams, domājat par citiem atvērtā pirmkoda vai saistītiem projektiem, kurus vēlaties izmantot, un esat pārsteigts, ka es tos neesmu komentējis.

Kā ar IBM SOAP4J?

Pirmais alternatīvu sarakstā ir IBM implementācija: SOAP4J. IBM darbs veidoja Apache SOAP projekta pamatu, tāpat kā IBM XML4J kļuva par to, kas tagad pazīstams kā Apache Xerces XML parsētājs. Tiek pieņemts, ka IBM ieviešana tiks pārveidota, apvienojot to ar Apache SOAP. Tas pats notika ar IBM XML4J: tagad tas nodrošina tikai iesaiņojumu Xerces. Tas tikai izceļ tendences - lielie ražotāji bieži atbalsta un izmanto OpenSource projektus, šajā gadījumā abi projekti (Apache un IBM) izmanto vienu un to pašu kodu bāzi.

Vai Microsoft ir ārpus spēles?

Protams ka nē. Microsoft un tā SOAP ieviešana, kā arī visa .NET kustība (sīkāk apspriesta manā grāmatā) ir diezgan nozīmīga. Es tiešām gribēju pavadīt lielāko daļu sava laika, lai detalizēti aplūkotu Microsoft SOAP ieviešanu, taču tas atbalsta tikai COM objektus un neatbalsta Java. Šo iemeslu dēļ šādu aprakstu nevarēja iekļaut rakstā par Java un XML. Tomēr Microsoft (neskatoties uz visām sūdzībām, kas mums kā izstrādātājiem ir par šo uzņēmumu) ir paveicis nozīmīgu darbu tīmekļa pakalpojumu jomā, un jūs kļūdīsities, ja atlaidīsit to nedomājot, tikai jēlu emociju vadīts. Ja jums ir nepieciešams strādāt ar COM vai Visual Basic komponentiem, ļoti iesaku izmēģināt Microsoft SOAP rīku komplektu, kas pieejams vietnē http://msdn.microsoft.com/library/default.asp?url=/nhp/Default .asp ?contentid=28000523 kopā ar daudziem citiem SOAP resursiem.

Kas ir Axis?

Tie, kas seko Apache aktivitātēm, noteikti ir dzirdējuši par Apache Axis. Axis ir nākamās paaudzes SOAP rīku komplekts, kas arī izstrādāts Apache XML jumta ietvaros. SOAP (specifikācija, nevis konkrēta ieviešana), kas pēdējā laikā strauji un radikāli attīstās, ir ļoti grūti izsekot. Mēģinājums izveidot SOAP versiju, kas pilnībā atbilst pašreizējām prasībām to attīstības gaitā, arī ir diezgan sarežģīts uzdevums. Rezultātā pašreizējā Apache SOAP versija piedāvā risinājumu, ko ierobežo tās dizains. Nolēmuši, ka nav vērts mēģināt pilnībā pārveidot esošo rīku, Apache izstrādātāji sāka veidot projektu, pamatojoties uz jauno kodu. Tā radās Axis. Mainījās arī SOAP nosaukums, vispirms no SOAP uz XP un pēc tam uz XMLP. Tad specifikācijas nosaukums tika izmests no jaunā SOAP nosaukuma un radās nosaukums "Axis". Bet tagad izskatās, ka W3C atgriežas pie SOAP specifikācijas nosaukuma (versija 1.2 vai 2.0), tāpēc lietas joprojām var mainīties un būs vēl vairāk neskaidrību!

Domājiet par IBM SOAP4J kā SOAP rīku komplekta arhitektūru?1. Kā ar Apache SOAP (par to ir runāts šajā rakstā) kā arhitektūru?2. Un Axis pārstāv ?3 arhitektūru, jaunas paaudzes arhitektūru. Šis projekts izmanto SAX, savukārt Apache SOAP ir DOM pamatā. Turklāt Axis, atšķirībā no Apache SOAP, nodrošina lietotājam draudzīgāku pieeju lietotāja mijiedarbībai. Pēc šo priekšrocību uzskaitīšanas jums varētu rasties jautājums, kāpēc es neizvēlējos Axis par savu studiju priekšmetu. Tas būtu tikai nedaudz pāragri. Pašlaik izlaišanai tiek gatavota tikai Axis versija 0.51. Šī vēl nav beta versija vai pat alfa versija. Es labprāt pastāstītu par jaunajiem Axis līdzekļiem, taču jums nebūtu nekādu iespēju pārliecināt savu vadību, ka varat izmantot sub-alfa atvērtā pirmkoda programmatūru savām kritiskajām sistēmas vajadzībām. Tāpēc es nolēmu koncentrēties uz kaut ko tādu, kas tu esi īsts tu vari izmantot jau Šodien- Apache SOAP. Es domāju, ka līdz Apache Axis galīgajai versijai es atjaunināšu šo materiālu nākamajā savas grāmatas izdevumā. Līdz tam koncentrēsimies uz jau pieejamo risinājumu.

Uzstādīšana

Ir divi iespējamie SOAP instalēšanas veidi. Pirmais ir SOAP klienta palaišana, izmantojot SOAP API, lai sazinātos ar serveri, kas var pieņemt SOAP ziņojumus. Otrs veids ir palaist SOAP serveri, kas var saņemt ziņojumus no SOAP klienta. Šajā sadaļā esmu aprakstījis abas procedūras.

Klients

Lai izmantotu SOAP klientu, vispirms ir jālejupielādē Apache SOAP, kas pieejama vietnē http://xml.apache.org/dist/soap. Es lejupielādēju versiju 2.2 binārā formātā (no apakšdirektorijas versija-2.2). Pēc tam jums ir jāizpako arhīva saturs datora direktorijā. Manā gadījumā tas bija direktorijs javaxml2 (c:\javaxml2 manā Windows datorā /javaxml2 manā Mac OS X datorā). Rezultātā faili tika izspiesti /javaxml2/ziepes-2_2. Jums būs arī jālejupielādē JavaMail pakotne, kas pieejama vietnē Sun http://java.sun.com/products/javamail/. Tam būs jāatbalsta Apache SOAP izmantotais SMTP pārsūtīšanas protokols. Pēc tam lejupielādējiet Java Beans Activation Framework (JAF), kas pieejams arī vietnē Sun http://java.sun.com/products/beans/glasgow/jaf.html. Pamatojoties uz pieņēmumu, ka Xerces vai cits XML parsētājs jau ir instalēts un gatavs lietošanai.

Piezīme: Pārliecinieties, vai jūsu XML parsētājs ir saderīgs ar JAXP un pareizi izmanto nosaukumvietu. Jūsu parsētājs, visticamāk, atbilst šīm prasībām. Ja rodas problēmas, vislabāk ir atgriezties pie Xerces izmantošanas.

Piezīme: Izmantojiet jaunākās Xerces versijas. Derēs versija 1.4 un jaunāka versija. SOAP un Xerces 1.3(.1) ir vairākas kļūdas, tāpēc es neiesaku izmantot šo kombināciju.

Izpakojiet JavaMail un JAF pakotnes un pēc tam iekļaujiet to jar failus savā klases ceļā, kā arī bibliotēkā ziepes.burka. Katram no šiem jar failiem jāatrodas vai nu attiecīgās programmas saknes direktorijā, vai apakšdirektorijā /lib. Kad esat pabeidzis savu mainīgo klases ceļš vajadzētu izskatīties apmēram šādi:

$ echo $CLASSPATH /javaxml2/soap-2_2/lib/soap.jar:/javaxml2/lib/xerces.jar: /javaxml2/javamail-1.2/mail.jar:/javaxml2/jaf-1.0.1/activation.jar

Operētājsistēmai Windows tas izskatīsies šādi:

c:\>echo %CLASSPATH% c:\javaxml2\soap-2_2\lib\soap.jar;c:\javaxml2\lib\xerces.jar; c:\javaxml2\javamail-1.2\mail.jar;c:\javaxml2\jaf-1.0.1\activation.jar

Un visbeidzot pievienojiet direktoriju javaxml2/ziepes-2_2/ tavā klases ceļš lai palaistu SOAP piemērus. Šajā nodaļā esmu aprakstījis iestatīšanu vairākiem piemēriem.

Serveris

Lai izveidotu ar SOAP saderīgu servera komponentu kopu, vispirms ir nepieciešams servleta dzinējs. Tāpat kā iepriekšējās nodaļās, kā piemēru šai nodaļai izmantoju Apache Tomcat (pieejams vietnē http://jakarta.apache.org/). Jums būs jāpievieno viss klientam nepieciešamais klases ceļš serveris. Vienkāršākais veids, kā to izdarīt, ir atiestatīt ziepes.burka, aktivizēšana.jar Un pasts.jar, kā arī parsētājs, jūsu servlet dzinēja bibliotēku direktorijā. Tomcat tas ir /lib direktorijs, kurā ir bibliotēkas automātiskai ielādei. Ja vēlaties nodrošināt atbalstu skriptiem (kas nav apskatīti šajā nodaļā, bet ir Apache SOAP piemēros), jums jāievieto bsf.jar(pieejams vietnē http://oss.software.ibm.com/developerworks/projects/bsf) un js.jar(pieejams vietnē http://www.mozilla.org/rhino/) tajā pašā direktorijā.

Piezīme: Ja izmantojat Xerces kopā ar Tomcat, jums būs jāatkārto triks, par kuru es runāju 10. nodaļā. Pārdēvēt parser.jar V z_parser.jar, A jaxp.jar V z_jaxp.jar lai par to pārliecinātos xerces.jar un iekļautā JAXP versija tiek ielādēta pirms jebkura cita parsētāja vai JAXP ieviešanas.

Pēc tam restartējiet servleta dzinēju, pēc kura esat gatavs rakstīt SOAP servera komponentus.

Maršrutētāja Servlet un Admin Client

Papildus pamata darbībām Apache SOAP ietver maršrutētāja servletu, kā arī administratora klientu. Pat ja jūs neplānojat tos izmantot, es iesaku tos instalēt, lai pārbaudītu, vai SOAP ir instalēts pareizi. Šis process ir atkarīgs no tā, kuru servleta dzinēju izmantojat, tāpēc es ierobežošu instalēšanas procesu ar Tomcat. Dažu citu servletu dzinēju instalēšanas instrukcijas var atrast vietnē http://xml.apache.org/soap/docs/index.html.

Instalēšana programmā Tomcat ir ļoti vienkārša: vienkārši paņemiet failu ziepes.karš no direktorija ziepes-2_2/webapps un nometiet to direktorijā $TOMCAT_HOME/webapps- un tas arī viss! Lai pārbaudītu instalāciju, pārlūkprogrammā ievadiet adresi http://localhost:8080/soap/servlet/rpcrouter. Jums vajadzētu saņemt atbildi, kas ir līdzīga tai, kas parādīta 12-2. attēlā.

Attēls 12-2. Maršrutētāja RPC Servlet

Lai gan šķiet, ka ziņojums ir kļūdas ziņojums, tas norāda, ka viss darbojas pareizi. Tāda pati atbilde jāsaņem, ja pārlūkprogrammā norādāt administratora klienta adresi: http://localhost:8080/soap/servlet/messagerouter.

Lai pabeigtu servera un klienta testēšanu, pārliecinieties, vai esat pilnībā izpildījis visus norādījumus. Pēc tam palaidiet šādu Java klasi, kā parādīts tālāk, lai atbalstītu servleta URL RPC maršrutētāja servletam:

C:\>java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter saraksts Izvietotie pakalpojumi:

Jums vajadzētu iegūt tukšu pakalpojumu sarakstu, kā parādīts iepriekš. Ja saņemat ziņojumus, lūdzu, pārskatiet garo iespējamo kļūdu sarakstu, kas pieejams vietnē http://xml.apache.org/soap/docs/trouble/index.html. Šis ir visplašākais problēmu saraksts, ar kurām jūs varētu saskarties. Ja saņemat tukšu sarakstu, tas nozīmē, ka iestatīšana ir pabeigta un esat gatavs sākt aplūkot šajā nodaļā sniegtos piemērus.

Sāksim

Jebkuras uz SOAP balstītas sistēmas rakstīšanai ir trīs galvenie posmi. Uzskaitot tos, es īsi apspriedīšu katru no tiem:

  • Izvēle starp SOAP-RPC un SOAP ziņojumiem;
  • Rakstīšana vai piekļuves iegūšana SOAP pakalpojumam;
  • Rakstīšana vai piekļuve SOAP klientam.

Pirmais solis ir izvēlēties, vai izmantosit SOAP RPC izsaukumiem (kurā serverī tiek izpildīta attālināta procedūra) vai ziņojumiem (kuros klients vienkārši nosūta serverim informāciju). Tālāk es sīkāk aplūkošu šos procesus. Kad esat pieņēmis šo lēmumu, jums būs jāpiekļūst vai jāizveido savs pakalpojums. Protams, tā kā mēs visi esam Java profesionāļi, šajā nodaļā ir aprakstīts, kā izveidot savu. Un visbeidzot, jums ir jāraksta klients šim pakalpojumam, tas arī viss!

RPC vai ziņojumapmaiņa?

Jūsu pirmajam uzdevumam nav nekā kopīga ar programmēšanu, un tas ir vairāk dizaina raksturs. Jums ir jāizvēlas, vai izmantosit RPC vai ziņojumu pakalpojumu. Mēs pieņemsim, ka esat iepazinies ar RPC (piemēram, izlasot kādu no manas grāmatas nodaļām). Klients serverī izpilda attālinātu procedūru un pēc tam saņem atbildi. Šajā scenārijā SOAP darbojas kā uzlabota XML-RPC sistēma, kas nodrošina labāku kļūdu apstrādi un sarežģītu datu tipu pārsūtīšanu tīklā. Jūs jau esat iepazinies ar šo koncepciju, un, tā kā RPC sistēmas ir vieglāk rakstīt SOAP, es sākšu ar tām. Šajā rakstā ir aprakstīts, kā izveidot RPC pakalpojumu, RPC klientu un ieviest sistēmu ražošanā.

Vēl viens SOAP darbības veids ir balstīts uz ziņojumu apmaiņu. Tā vietā, lai veiktu attālinātas procedūras, to izmanto tikai informācijas apmaiņai. Kā jau nojaušat, šis ir spēcīgs rīks, kas neprasa klientam zināt jebkura servera individuālās metodes. Tas arī padara attālo sistēmu modelēšanu izolētāku, ļaujot datu paketes (paketes pārnestā nozīmē, nevis tīkla nozīmē) nosūtīt uz citām sistēmām. Tajā pašā laikā citām sistēmām nav jāzina par darbībām, kas tika veiktas ar šiem datiem. Šis stils ir sarežģītāks par RPC programmēšanu, tāpēc es to šeit neaprakstīšu. Jūs to atradīsit manā grāmatā, kā arī citu informāciju par uzņēmumu savstarpējo mijiedarbību. Vispirms iepazīstieties ar SOAP-RPC programmēšanu.

Tāpat kā lielākā daļa dizaina problēmu, šī lēmuma pieņemšana ir jūsu ziņā. Analizējiet savu lietojumprogrammu un mēģiniet noteikt, kāpēc jums ir jāizmanto SOAP. Ja jums ir serveris un klientu kopums, kas pēc pieprasījuma veic noteiktas biznesa funkcijas, tad RPC jums ir piemērotāks. Sarežģītās sistēmās, kurās datu apmaiņa ir vairāk nekā tikai konkrētu biznesa funkciju veikšana pēc pieprasījuma, daudz vēlams izmantot SOAP ziņojumus.

RPC pakalpojums

Tagad, kad formalitātes ir beigušās, ir pienācis laiks rīkoties. Kā zināms, RPC jums būs nepieciešamas klases, kuru metodes tiks izpildītas attālināti.

Koda fragmenti

Sākšu, apskatot dažus servera koda fragmentus. Šie fragmenti ir klases ar metodēm, kas tiek izpildītas RPC klientiem. Kā piemērus izmantoju kodu no savas grāmatas. Tā vietā, lai izmantotu vienkāršas klases, es izvēlējos sarežģītāku piemēru, lai pēc iespējas skaidrāk parādītu SOAP iespējas. Tātad, es izmantoju CD klasi kā piemēru. Vispirms mēs definējam elementu karte katram nestandarta parametra veidam. Par atribūtu kodēšanas stils, vismaz Apache SOAP 2.2. jums ir jānorāda vērtība http://schemas.xmlsoap.org/soap/encoding/ . Pašlaik šis ir vienīgais atbalstītais kodējums. Jums ir jānorāda lietotāja definētā tipa nosaukumvieta un pēc tam klases nosaukums ar prefiksu ar šī tipa nosaukumvietu. Mūsu gadījumā šiem nolūkiem es izmantoju fiktīvu nosaukumvietu un vienkāršu prefiksu " x". Pēc tam izmantojiet atribūtu javaType, iestatiet Java klases īsto nosaukumu (šajā gadījumā - javaxml2.CD). Un visbeidzot, kuralesil ar atribūtiem java2XMLClassName Un xml2JavaClassName. Ar viņu palīdzību tiek norādīta klase, kas tiek pārveidota no Java uz XML un otrādi. Es izmantoju pārsteidzoši ērto BeanSerializer klasi, kas iekļauta arī Apache SOAP. Ja jūsu pielāgotais parametrs ir JavaBean formātā, šis serializētājs un deserializētājs neļaus jums rakstīt savu. Jums ir nepieciešama klase ar noklusējuma konstruktoru (atcerieties, ka CD klasei es definēju vienkāršu bezparametru konstruktoru) un publicējiet visus šīs klases datus, izmantojot metodes iestatītXXX Un saņemt XXX. Jo klase CD lieliski atbilst visām šīm prasībām, BeanSerializer strādā perfekti.

Piezīme: Kāda klase CD atbilst prasībām BeanSerializer. nav lielas nozīmes. Lielāko daļu nodarbību var viegli pārveidot šajā formātā. Tāpēc es iesaku nerakstīt savus serializētājus un deserializatorus. Šīs ir papildu galvassāpes (nekas nav sarežģīts, bet pārāk rūpīgs), un es iesaku taupīt enerģiju un izmantot pupiņu pārveidošanu savos pielāgotajos parametros. Daudzos gadījumos pupiņu reklāmguvumiem jūsu klasē ir nepieciešams tikai noklusējuma konstruktors (bez parametriem).

Tagad veidosim no jauna burka failu un atkārtoti instalējiet mūsu pakalpojumu:

(gandalf)/javaxml2/Ch12$ java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter xml/CDCatalogDD.xml

Uzmanību: Ja atstājat servleta dzinēju darboties un vienlaikus atkārtoti mitināt pakalpojumu, jums būs jārestartē servleta programma, lai iespējotu jaunās klases SOAP pakalpojumam un atkārtoti mitinātu pakalpojumu.

Tagad atliek tikai modificēt klientu, lai tas izmantotu jaunas klases un metodes. Piemērā 12-10 ir modificēta klienta klases versija CDAdder. Iepriekšējā versijā veiktās izmaiņas ir iezīmētas.

Piemērs 12-10: Atjaunināta CDAdder klase

pakotne javaxml2; importēt java.net.URL; importēt java.util.Vector; importēt org.apache.soap.Constants; importēt org.apache.soap.Fault; importēt org.apache.soap.SOAPException; importēt org.apache.soap.encoding.SOAPMappingRegistry; importēt org.apache.soap.encoding.soapenc.BeanSerializer; importēt org.apache.soap.rpc.Call; importēt org.apache.soap.rpc.Parameter; importēt org.apache.soap.rpc.Response; importēt org.apache.soap.util.xml.QName; publiskās klases CDAdder( public void add(URL URL, Virknes nosaukums, Virknes izpildītājs, Virknes etiķete) izmet SOAPException ( System.out.println("CD pievienošana ar nosaukumu "" + nosaukums + "" izpildītājs "" + izpildītājs + "" studija " + etiķete); CD cd = jauns CD(nosaukums, izpildītājs, etiķete); // Izveidot zvana objektu Call Call call = new Call(); call.setSOAPMappingRegistry(reģistrs); call.setTargetObjectURI("urn:cd-catalog"); call.setMethodName("addCD"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); // Parametru iestatīšana Vector params = new Vector(); params.addElement(new Parameter("cd", CD.class, cd, null)); call.setParams(params); // Notiek Invoke call Response atbildes apstrāde; atbilde = call.invoke(url, ""); if (!response.generatedFault()) ( System.out.println("CD pievienošana ir veiksmīgi pabeigta."); ) else ( Fault fault = response.getFault(); System.out.println(Kļūda: " + fault.getFaultString ()); ) ) public static void main(String args) ( if (args.length != 4) ( System.out.println("Veidne: java javaxml2.CDAdder " + "\"[CD nosaukums]\" \"[mākslinieka vārds]\ " \"[Studijas kompaktdisks]\""); atgriezties; ) try ( // SOAP servera URL, ar kuru tiek izveidots savienojums URL url = new URL(args); // Iegūt vērtības jaunajam kompaktdiska virknes nosaukumam = args; Stīgu mākslinieks = args; Virknes etiķete = args; // Pievienot CD CDAdder papildinātāju = new CDAdder(); adder.add(url, nosaukums, izpildītājs, etiķete); ) noķert (e. izņēmums) ( e.printStackTrace(); ) ) )

Vienīgās patiešām interesantās izmaiņas ir klases kartēšanā CD:

// Kartē šo tipu, lai to varētu izmantot ar SOAP SOAPMappingRegistry reģistrs = new SOAPMappingRegistry(); BeanSerializer serializer = jauns BeanSerializer(); registry.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("urn:cd-catalog-demo", "cd"), CD.class, serializer, serializer);

Tādā veidā lietotāja parametru var kodēt un pārsūtīt tīklā. Es jau teicu, kā klasē BeanSerializer var izmantot, lai apstrādātu parametrus JavaBean formātā, piemēram, klasi CD. Es izmantoju izvietojuma deskriptoru, lai norādītu tos uz serveri, lai gan tagad man ir jāpasaka klientam, lai tas izmantotu šo serializer un deserializer. Šo funkciju veic klase SOAPMappingRegistry. Metode kartes tipi()ņem šifrētu virkni (atkal labāk šim nolūkam izmantot konstanti NS_URI_SOAP_ENC), un informācija par parametra veidu, kuram jāizmanto īpaša serializācija. Vispirms tiek norādīts QName. Tāpēc mitināšanas deskriptorā tika izmantota dīvainā nosaukumvieta. Šeit ir jānorāda tas pats URN, kā arī elementa vietējais nosaukums (šajā piemērā "CD"), pēc tam Java objekts Klase klase, kas tiks serializēta ( CD.klase) un visbeidzot serializācijas un deserializācijas klases gadījumu. Šajā piemērā abos gadījumos tiks iesaistīta instance BeanSerializer. Kad visi šie iestatījumi ir ievadīti reģistrā, paziņojiet objektam Zvaniet izmantojot metodi setSOAPMapping-Registry().

Varat palaist šo klasi, kā parādīts iepriekš, pievienojot kompaktdisku, un visam vajadzētu darboties, kā paredzēts:

C:\javaxml2\build>java javaxml2.CDAdder http://localhost:8080/soap/servlet/rpcrouter "Tony Rice" "Manzanita" "Sugar Hill" CD pievienošana ar nosaukumu "Tony Rice" no Sugar Hill grupas "Manzanita" Veiksmīgi pievienots kompaktdisks.

Es atstāju klases modifikāciju CDLister tev. Viss tiek ražots pēc vienas veidnes. Lai pārbaudītu sevi, varat skatīt manas grāmatas piemēru failus, kuros jau ir šīs atjauninātās klases.

Piezīme. Varat to izlemt, jo klasē CDLister tieši nesadarbojas ar objektu CD(atgriezts pēc metodes saraksts () veidam ir nozīme Hashtable), tad jums nav jāveic nekādas izmaiņas. Tomēr atgriezās klase Hashtable satur objektu gadījumus CD. Ja SOAP nezina, kā tos deserializēt, klients parādīs kļūdu. Šajā gadījumā, lai atrisinātu problēmu, jums ir jānorāda objektā Zvaniet kopiju SOAPMappingRegistry.

Efektīva kļūdu apstrāde

Tagad, kad esat redzējis pielāgotus objektus un veicis RPC zvanus un citas lietas, ļaujiet man runāt par mazāk aizraujošu tēmu: kļūdu apstrādi. Ar jebkuru tīkla darījumu var rasties daudzas kļūmes. Pakalpojums nesākas, serverī ir kļūda, objektu nevar atrast, trūkst klases un daudzas citas problēmas. Līdz šim es vienkārši izmantoju šo metodi fault.getString() lai ģenerētu kļūdu ziņojumus. Bet šī metode ne vienmēr var būt noderīga. Lai to redzētu darbībā, atceliet konstruktora komentāru CD katalogs:

publiskais CDCatalog() ( //catalog = new Hashtable(); // Izveidot direktoriju addCD(new CD("Nickel Creek", "Nickel Creek", "Sugar Hill")); addCD(jauns CD("Let it Fall", "Sean Watkins", "Sugar Hill")); addCD(jauns CD("Aerial Boundaries", "Michael Hedges", "Windham Hill")); addCD(jauns kompaktdisks ("Taproot", "Maikls Hedžess", "Vindhamhils")); )

Pārkompilējiet to, restartējiet servleta dzinēju un atkārtoti mitiniet to. Tas radīs izņēmumu NullPointerException kad klases konstruktors mēģina pievienot CD uninicializētam Hashtable. Startējot klientu, parādīsies kļūdas ziņojums, taču tas nebūs īpaši informatīvs:

(gandalf)/javaxml2/build$ java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcrouter Skatiet pašreizējo kompaktdiska direktoriju. Kļūda: nevar atrisināt mērķa objektu: null

Šī nepavisam nav tā informācija, kas var palīdzēt identificēt un labot kļūdu. Tomēr sistēma pareizi tiek galā ar kļūdu apstrādi. Vai tu atceries DOMFaultListener, kuru norādījāt kā elementa vērtību kļūdaKlausītājs? Viņam ir pienācis laiks iesaistīties spēlē. Objekts tika atgriezts kļūdas gadījumā Vaina satur DOM (dokumenta objekta modeli) org.w3c.dom.Element ar detalizētu informāciju par kļūdu. Vispirms pievienojiet importēšanas izteiksmi savam avota kodam java.util.Iterator:

importēt java.net.URL; importēt java.util.Enumeration; importēt java.util.Hashtable; importēt java.util.Iterator; importēt java.util.Vector; importēt org.apache.soap.Constants; importēt org.apache.soap.Fault; importēt org.apache.soap.SOAPException; importēt org.apache.soap.encoding.SOAPMappingRegistry; importēt org.apache.soap.encoding.soapenc.BeanSerializer; importēt org.apache.soap.rpc.Call; importēt org.apache.soap.rpc.Parameter; importēt org.apache.soap.rpc.Response; importēt org.apache.soap.util.xml.QName;

Tagad veiksim izmaiņas, lai apstrādātu kļūdas sarakstā() metodē:

if (!response.generatedFault()) ( Parametrs returnValue = response.getReturnValue(); Hashtable katalogs = (Hashtable)returnValue.getValue(); Uzskaitījums e = catalog.keys(); while (e.hasMoreElements()) ( String title = (String)e.nextElement(); CD cd = (CD)catalog.get(title); System.out.println(" "" + cd.getTitle() + "" izpildītājs " + cd.getArtist() + " studios " + cd.getLabel()); ) ) else ( Fault fault = response.getFault(); System.out.println("Kļūda: " + fault.getFaultString()); Vektoru ieraksti = fault.getDetailEntries(); for (Iterator i = entries.iterator(); i.hasNext();) ( org.w3c.dom.Element entry = (org.w3c.dom.Element)i.next(); System.out.println(entry .getFirstChild().getNodeValue()); ) )

Izmantojot metodi getDetailEntries() jūs saņemat piekļuvi SOAP pakalpojumam un neapstrādāto datu serverim, kas atbalsta problēmu. Kods tos atkārtoti apstrādā (parasti ir tikai viens elements, bet tam ir jāpievērš īpaša uzmanība) un pārtver DOM Elements, kas ietverti katrā ierakstā. Būtībā šeit ir XML, ar kuru strādājat:

SOAP-ENV:Server.BadTargetObjectURI Nevar atrisināt mērķi: null Tas ir tas, ko mēs vēlamies!

Citiem vārdiem sakot, objekts Fault nodrošina piekļuvi tai SOAP aploksnes daļai, kurā ir kļūdas. Turklāt Apache SOAP nodrošina Java steka izsekošanu, kad rodas kļūdas, sniedzot detalizētu informāciju, kas nepieciešama to labošanai. Elementa pārtveršana stackTrace un izdrukājot mezgla vērtību Teksts no šī elementa jūsu klients var izdrukāt servera steka izsekojumu. Apkopojot šīs izmaiņas un restartējot klientu, jūs iegūsit šādu rezultātu:

C:\javaxml2\build>java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcr outer Skatiet pašreizējo kompaktdiska direktoriju. Kļūda: nevar atrisināt mērķi: null java.lang.NullPointerException javaxml2.CDCatalog.addCD(CDCatalog.java:24) failā javaxml2.CDCatalog. (CDCatalog.java:14) valodā java.lang.Class.newInstance0(Native Method) valodā java.lang.Class.newInstance(Class.java:237)

Tas nav daudz labāks, bet vismaz jūs varat redzēt dažus informācijas sīkumus, ka ir noticis izņēmums NullPointerException un pat uzzināt rindu numurus serveru klasēs, kurās radās šī problēma. Šo neseno izmaiņu rezultāts ir sniedzis skaidru priekšstatu par kļūdu apstrādes problēmu. Tagad jums vajadzētu pārbaudīt, vai servera klasēs nav kļūdu. Jā, es gandrīz aizmirsu, pirms tam neaizmirstiet mainīt klasi CD katalogs lai atbrīvotos no kļūdām, kuras mēs apzināti ieviesām skaidrības labad!

  1. Daudz tiek runāts par SOAP palaišanu, izmantojot citus protokolus, piemēram, SMTP (vai pat Jabber). SOAP standarts pašlaik to nenodrošina, taču nākotnē var tikt pievienotas līdzīgas iespējas. Tāpēc nebrīnieties, ja par šo tēmu saskaraties ar aktīvām diskusijām.