Организирање на веб-услуги


капи 23 јули 2013 година во 13:09 часот

Пишување SOAP клиент-сервер апликација во PHP

  • PHP
  • упатство

Здраво на сите!
Така се случи што неодамна се вклучив во развојот на веб-услуги. Но, денес темата не е за мене, туку за тоа како можеме да напишеме сопствена веб-сервис XML врз основа на протоколот SOAP 1.2.

Се надевам дека откако ќе ја прочитате темата, ќе можете:

  • напишете свој сервер имплементација на веб апликација;
  • напишете своја сопствена клиентска имплементација на веб апликација;
  • напишете свој опис на веб-услуги (WSDL);
  • испраќање низи од ист тип на податоци до серверот од страна на клиентот.
Како што може да претпоставите, целата магија ќе се направи со користење на PHP и вградените класи SoapClient и SoapServer. Како зајак ќе имаме сервис за праќање смс пораки.

1 Изјава за проблемот

1.1 Граници

Во почетокот, предлагам да се справиме со резултатот што ќе го постигнеме на крајот од темата. Како што беше најавено погоре, ќе напишеме услуга за испраќање смс пораки, а поточно ќе добиваме пораки од различни извори со помош на протоколот SOAP. После тоа, ќе разгледаме во каква форма доаѓаат на серверот. Процесот на редица пораки за понатамошно испраќање до давателот, за жал, е надвор од опсегот на оваа објава поради многу причини.

1.2 Кои податоци ќе се променат?

Во ред, ги имаме границите! Следниот чекор што треба да се направи е да одлучиме кои податоци ќе ги размениме помеѓу серверот и клиентот. На оваа тема, предлагам да не бидете помудри долго време и веднаш да одговорите на главните прашања за себе:
  • Кои минимум податоци мора да се испратат до серверот за да се испрати СМС порака до претплатникот?
  • Која е минималната количина на податоци што мора да се испратат од серверот за да се задоволат потребите на клиентот?
Нешто ми кажува дека за ова е неопходно да се испрати следново:
  • број на мобилен телефон и
  • СМС текст.
Во принцип овие две карактеристики се доволни за испраќање, но веднаш ми се чини дека во 3 часот по полноќ или 4 ти доаѓа смс со роденденска честитка! Во овој момент ќе бидам многу благодарен на сите што не заборавија на мене! Затоа, ние исто така ќе испратиме до серверот и
  • датумот кога е испратена СМС пораката.
Следното нешто што би сакал да го испратам на серверот е
  • Тип на порака.
Овој параметар не е задолжителен, но може да ни биде многу корисен ако треба брзо да му кажеме на шефот колку од нашите клиенти сме „воодушевиле“ со нашите вести, а исто така да извлечеме убава статистика за ова прашање.

А сепак, заборавив нешто! Ако размислиме малку повеќе, вреди да се напомене дека клиентот може да испрати по една СМС порака на серверот или одреден број од нив. Со други зборови, во еден пакет со податоци може да има од една до бесконечност пораки.

Како резултат на тоа, добиваме дека за да испратиме СМС порака, потребни ни се следниве податоци:

  • број на мобилен телефон,
  • СМС текст,
  • времето на испраќање СМС порака до претплатник,
  • тип на порака.

Ние одговоривме на првото прашање, сега треба да одговориме на второто прашање. И можеби ќе си дозволам малку да изневерам. Затоа, од серверот ќе испраќаме само булови податоци, чија вредност го има следново значење:

  • ВИСТИНА - пакетот успешно стигна до серверот, помина автентикација и беше во ред за испраќање до давателот на смс
  • НЕТОЧНО - во сите други случаи

Ова го завршува описот на изјавата за проблемот! И, конечно, да се спуштиме на најинтересниот дел - ќе откриеме каков чуден ѕвер е овој САПУН!

2 Што е САПУН?

Во принцип, првично не планирав да пишувам ништо за тоа што е SOAP и сакав да се ограничам на линкови до страницата w3.org со потребните спецификации, како и врски до Википедија. Но, на самиот крај решив да напишам кратка референца за овој протокол.

И ќе ја започнам мојата приказна со фактот дека овој протокол за размена на податоци припаѓа на подмножество протоколи засновани на таканаречената парадигма RPC (Remote Procedure Call), чиј антипод е REST (претставнички државен пренос, пренос на репрезентативна држава). . Можете да прочитате повеќе за ова на Википедија, линковите до статиите се на самиот крај на темата. Од овие статии, треба да го разбереме следново: „Пристапот RPC ви овозможува да користите мала количина мрежни ресурси со голем број методи и сложен протокол. Со пристапот REST, бројот на методи и сложеноста на протоколот се строго ограничени, што може да доведе до голем број на индивидуални ресурси. Односно, во однос на нас, тоа значи дека во случајот со пристапот RPC, страницата секогаш ќе има еден влез (линк) до услугата и која процедура да се јави за обработка на дојдовните податоци што ги пренесуваме заедно со податоците, додека со пристапот REST на нашата Сајтот има многу влезови (линкови), од кои секоја прифаќа и обработува само одредени податоци. Ако некој што чита знае уште полесно да ја објасни разликата во овие пристапи, тогаш задолжително пишете во коментари!

Следното нешто што треба да го знаеме за SOAP е дека овој протокол го користи истиот XML како транспорт, што, од една страна, е многу добро, бидејќи. нашиот арсенал веднаш ја вклучува целосната моќ на купот технологии базирани на овој јазик за обележување, имено XML-Schema - јазик за опишување на структурата на XML документ (благодарение на Википедија!), кој овозможува автоматска валидација на податоците што пристигнуваат на серверот од клиенти.

И така, сега знаеме дека SOAP е протоколот што се користи за спроведување на далечинска процедура повик и користи XML како транспорт! Ако ја прочитате статијата на Википедија, тогаш од таму можете да научите и дека може да се користи преку кој било протокол на апликациски слој, а не само да се спарува со HTTP (за жал, во оваа тема ќе го разгледаме само SOAP преку HTTP). И знаете што најмногу ми се допаѓа во сето ова? Ако нема нагаѓања, тогаш ќе ви дадам навестување - САПУН!... Во секој случај нема нагаѓања?... Дали дефинитивно ја прочитавте статијата на Википедија?... Во принцип, нема да ве измачувам понатаму. Затоа, веднаш ќе преминам на одговорот: „SOAP (од англискиот. Протокол за пристап до едноставен објект - едноставен протоколпристап до објекти; до спецификација 1.2)“. Врвот на оваа линија е во закосени букви! Не знам какви заклучоци извлековте од сето ова, но го гледам следново - бидејќи овој протокол во никој случај не може да се нарече „едноставен“ (и очигледно дури и w3 се согласува со ова), тогаш од верзијата 1.2 престана да биде воопшто дешифрирано! И стана познат како САПУН, само САПУН и точка.

Па, во ред, се молам за простување, се лизна малку на страна. Како што напишав претходно, XML се користи како транспорт, а пакетите што се движат помеѓу клиентот и серверот се нарекуваат SOAP пликови. Ако ја земеме предвид генерализираната структура на пликот, тогаш ќе ви изгледа многу познато, бидејќи наликува на структурата на HTML страница. Има главен дел - Обвиваат, кој вклучува делови заглавиеи Тело, или Грешка. AT Телосе пренесуваат податоци и тоа е задолжителен дел од пликот, додека заглавиее опционален. AT заглавиеможе да се пренесе овластување или кој било друг податок што не е директно поврзан со влезните податоци на процедурите на веб-услугите. Про Грешканема ништо посебно да се каже, освен што доаѓа до клиентот од серверот во случај на некакви грешки.

Овде завршува мојата прегледна приказна за протоколот SOAP (ќе ги разгледаме самите пликови и нивната структура подетално кога нашиот клиент и сервер конечно ќе научат како да ги вклучат еден со друг) и започнува нова - за придружник на SOAP повикани WSDL(Јазик за опис на веб-услуги). Да, да, тоа е токму она што повеќето од нас ги плаши од самиот обид да се преземе и имплементира сопствен API на овој протокол. Како резултат на тоа, ние обично повторно го измислуваме нашето тркало со JSON како транспорт. Значи, што е WSDL? WSDL е јазик за опишување на веб-услуги и пристап до нив, врз основа на јазикот на Википедија XML (c). Ако од оваа дефиниција не ви стане јасно целото свето значење на оваа технологија, тогаш ќе се обидам да го опишам со свои зборови!

WSDL е дизајниран да им овозможи на нашите клиенти нормално да комуницираат со серверот. За да го направите ова, следните информации се опишани во датотеката со екстензија „*.wsdl“:

  • Кои именски простори се користеле,
  • Кои шеми за податоци се користени,
  • Какви видови пораки очекува веб сервисот од клиентите,
  • Кои податоци припаѓаат на кои процедури за веб сервиси,
  • Кои процедури ги содржи веб-услугата,
  • Како клиентот треба да ги повика процедурите за веб-услуги,
  • На која адреса треба да се испраќаат повиците на клиентот.
Како што можете да видите, оваа датотека е целата веб-услуга. Со наведување на адресата на датотеката WSDL во клиентот, ќе знаеме сè за која било веб-услуга! Како резултат на тоа, не треба да знаеме апсолутно ништо за тоа каде се наоѓа самата веб-услуга. Доволно е да се знае локацијата на нејзината WSDL датотека! Наскоро ќе дознаеме дека САПУН не е толку страшен како што е насликан (в) руска поговорка.

3 Вовед во XML шема

Сега знаеме многу за тоа што е САПУН, што има внатре во него и имаме преглед каков вид на технолошки оџак го опкружува. Бидејќи, пред сè, SOAP е метод на интеракција помеѓу клиентот и серверот, а јазикот за означување на XML се користи како транспорт за него, во овој дел малку ќе разбереме како се случува автоматската валидација на податоците преку XML шемите.

Главната задача на шемата е да ја опише структурата на податоците што ќе ги обработиме. Сите податоци во XML шемите се поделени на едноставно(скаларен) и комплекс(структурира) типови. Едноставните типови вклучуваат такви типови како што се:

  • линија,
  • број,
  • бул,
  • датумот.
Нешто многу едноставно што нема екстензии внатре. Нивниот антипод е сложен комплексен тип. Наједноставниот пример за сложен тип што на сите им паѓа на ум се предметите. На пример, книга. Книгата се состои од својства: автор, Наслов, цена, ISBN бројитн. И овие својства, пак, можат да бидат и едноставни типови и сложени. И задачата на XML шемата е да ја опише.

Предлагам да не одиме далеку и да пишуваме XML шема за нашата смс порака! Подолу е описот на xml на смс пораката:

71239876543 Тест порака 2013-07-20 T12:00:00 12
Нашата шема на комплексен тип ќе изгледа вака:


Овој запис гласи вака: имаме променлива " порака» тип » порака„и постои сложен тип со име“ порака", кој се состои од секвенцијален сет на елементи" телефон» тип низа, « текст» тип низа, « датум» тип датум време, « тип» тип децимална. Овие типови се едноставни и веќе се дефинирани во дефиницијата на шемата. Секоја чест! Штотуку ја напишавме нашата прва XML шема!

Мислам дека значењето на елементите " елемент"и" комплекс Тип» Сè ви стана горе-долу јасно, па нема да се фокусираме повеќе на нив и веднаш да се префрлиме на композиторскиот елемент « низа“. Кога го користиме композиторскиот елемент " низа» ве известуваме дека елементите вклучени во него мора секогаш да бидат во редоследот наведен во шемата, а исто така сите се задолжителни. Но, не очајувајте! Во XML шемите има уште два композиторски елементи: избор"и" сите“. Композитор избор" означува дека треба да има еден од елементите наведени во него, а композиторот " сите» – која било комбинација од наведените елементи.

Како што се сеќавате, во првиот дел од темата, се договоривме пакетот да може да се пренесува од една до бесконечност на смс пораки. Затоа, предлагам да се разбере како таквите податоци се декларирани во шемата XML. Општата структура на пакетот може да изгледа вака:

71239876543 Тест порака 1 2013-07-20 T12:00:00 12 71239876543 Тест порака Н 2013-07-20 T12:00:00 12
Шемата за таков комплексен тип би изгледала вака:


Првиот блок ја содржи познатата декларација на сложениот тип „ порака“. Ако забележите, тогаш во секој едноставен тип вклучен во " порака“, додадени се нови квалификациски атрибути “ мин се јавува"и" maxOccurs“. Како што не е тешко да се погоди од името, првиот ( мин се јавува) покажува дека дадената низа мора да содржи барем еден елемент од типот " телефон», « текст», « датум"и" тип“, додека следниот ( maxOccurs) атрибутот ни изјавува дека има најмногу еден таков елемент во нашата низа. Како резултат на тоа, кога ги пишуваме нашите шеми за какви било податоци, ни се дава најширок избор за тоа како да ги конфигурираме!

Вториот блок од шемата го декларира елементот " Листа на пораки» тип » Список со пораки“. Јасно е дека " Список со пораки"е сложен тип кој вклучува најмалку еден елемент" порака“, но максималниот број на такви елементи не е ограничен!

4 Пишување на вашиот WSDL

Дали се сеќавате дека WSDL е нашата веб-услуга? Се надевам дека се сеќавате! Додека го пишуваме, нашиот мал веб сервис ќе лебди на него. Затоа предлагам да не изневеруваш.

Во принцип, за сè да работи правилно кај нас, треба да пренесеме WSDL-датотека со правилен тип MIME на клиентот. За да го направите ова, треба соодветно да го конфигурирате вашиот веб-сервер, имено, да го поставите типот MIME за датотеките со екстензија *.wsdl на следната линија:

Апликација/wsdl+xml
Но, во пракса, обично го испраќав заглавието на HTTP преку PHP " текст/xml»:

Header ("Content-Type: text/xml; charset=utf-8");
и сè функционираше одлично!

Сакам веднаш да ве предупредам, нашата едноставна веб-услуга ќе има прилично импресивен опис, затоа не се вознемирувајте, бидејќи. поголемиот дел од текстот е задолжителен вода и откако ќе се напише може постојано да се копира од еден веб сервис на друг!

Бидејќи WSDL е XML, тогаш во првата линија треба директно да пишувате за тоа. Главниот елемент на датотеката секогаш мора да биде именуван " дефиниции»:


Обично, WSDL се состои од 4-5 главни блокови. Првиот блок е дефиницијата за веб-услуга, или со други зборови, влезна точка.


Овде пишува дека имаме услуга наречена - " СМС услуга“. Во принцип, сите имиња во WSDL-датотеката може да се сменат од вас на што и да посакате, затоа што тие немаат апсолутно никаква улога.

После тоа, го изјавуваме тоа во нашата веб-сервис " СМС услуга" постои влезна точка ("порта"), која се нарекува " SmsServicePort“. До оваа влезна точка ќе бидат испратени сите барања од клиентите до серверот. И ние назначуваме во елементот " адреса» врска до датотека со управувач што ќе прифаќа барања.

Откако ќе дефинираме веб-услуга и ќе наведеме влезна точка за неа, треба да ги поврземе поддржаните процедури за неа:


За да го направите ова, наведува кои операции и во каква форма ќе се нарекуваат y. Оние. за пристаништето SmsServicePort» врзување со име „ SmsServiceBinding", кој има тип на повик" rpc” и HTTP се користи како протокол за пренос (транспорт). Така, овде наведовме дека ќе направиме RPC повик преку HTTP. После тоа, опишуваме кои процедури ( операција) се поддржани во веб-услугата. Ќе поддржиме само една постапка -“ прати СМС“. Преку оваа постапка, нашите прекрасни пораки ќе бидат испратени до серверот! По објавувањето на постапката, неопходно е да се наведе во каква форма ќе се пренесат податоците. Во овој случај, наведено е дека ќе се користат стандардни пликови за SOAP.

После тоа, треба да ја поврземе постапката со пораките:


За да го направите ова, наведуваме дека нашето врзување („врзување“) е од типот „ SmsServicePortType„и во елементот“ portType» со ист тип име, наведете го врзувањето на процедурите за пораките. И така, дојдовната порака (од клиентот до серверот) ќе се вика " sendSmsRequest", и појдовни (од серверот до клиентот)" sendSmsResponse“. Како и сите имиња во WSDL, имињата на дојдовните и појдовните пораки се произволни.

Сега треба да ги опишеме самите пораки, т.е. дојдовни и појдовни:


За да го направите ова, ги додаваме елементите " порака» со имиња „ sendSmsRequest"и" sendSmsResponse„соодветно. Во нив, укажуваме дека на влезот треба да дојде плик, чија структура одговара на типот на податоци " Барање“. После тоа, плик кој го содржи типот на податоци се враќа од серверот - " Одговор».

Сега треба да направиме само малку - да додадеме опис на овие типови во нашата WSDL-датотека! И како мислите дека WSDL ги опишува дојдовните и излезните податоци? Мислам дека одамна сте разбрале се и тоа си го кажавте со помош на XML шеми! И ќе бидете апсолутно во право!


Можете да ни честитате! Напишан е нашиот прв WSDL! И ние сме чекор поблиску до остварување на нашата цел.
Следно, ќе се занимаваме со она што ни го обезбедува PHP за развивање на сопствени дистрибуирани апликации.

5 Нашиот прв SOAP сервер

Претходно, напишав дека за да создадеме сервер за SOAP во PHP, ќе ја користиме вградената класа SoapServer. Со цел сите понатамошни дејства да се случат на ист начин како моите, ќе треба малку да го дотерате вашиот PHP. Да бидеме уште попрецизни, треба да се уверите дека ја имате инсталирано екстензијата „php-soap“. Како да го ставите на вашиот веб-сервер најдобро е да се прочита на официјалната веб-страница на PHP (види референци).

Откако сè ќе биде инсталирано и конфигурирано, ќе треба да ја создадеме датотеката “ smsservice.php» со следнава содржина:

setClass ("SoapSmsGateWay"); //Стартирајте го серверот $server->handle();
Она што е над линијата со функцијата „ini_set“, се надевам, не треба да се објаснува. Бидејќи дефинира кои HTTP заглавија ќе ги испратиме од серверот до клиентот и ја конфигурира околината. Во линијата „ini_set“, го оневозможуваме кеширањето на WSDL-датотеката, така што нашите промени во неа веднаш стапуваат на сила на клиентот.

Сега доаѓаме до серверот! Како што можете да видите, целиот сервер за SOAP е долг само три линии! Во првата линија, создаваме нов примерок од објектот SoapServer и ја пренесуваме адресата на описот на нашата веб-услуга WSDL на неговиот конструктор. Сега знаеме дека ќе се наоѓа во коренот на хостинг во датотека со гласно име " smsservice.wsdl.php“. Во втората линија, му кажуваме на серверот SOAP која класа да ја повлече за да го обработи пликот добиен од клиентот и да го врати пликот со одговорот. Како што може да претпоставите, во оваа класа ќе биде опишан нашиот единствен метод. прати СМС. Во третата линија го стартуваме серверот! Сè, нашиот сервер е подготвен! Со што ни честитам на сите!

Сега треба да создадеме WSDL-датотека. За да го направите ова, можете или едноставно да ја копирате неговата содржина од претходниот дел, или да се ослободите и малку да го „шаблонирате“:

"; ?> /" 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" />
Во оваа фаза, добиениот сервер треба целосно да ни одговара, бидејќи. можеме да ги евидентираме пликовите кои доаѓаат до него и потоа мирно да ги анализираме дојдовните податоци. За да добиеме било што на серверот, потребен ни е клиент. Па ајде да продолжиме со нив!

6 SOAP клиент на пат

Пред сè, треба да создадеме датотека во која ќе го запишеме клиентот. Како и обично, ќе го создадеме во коренот на домаќинот и ќе го наречеме " клиент.php“, а внатре го пишуваме следново:

messageList = нов MessageList(); $req->messageList->порака = нова Порака(); $req->messageList->порака->телефон = "79871234567"; $req->messageList->message->text = "Тест порака 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->порака->тип = 15; $client = new SoapClient ("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", низа ("soap_version" => SOAP_1_2)); var_dump($client->sendSms($req));
Ајде да ги опишеме нашите предмети. Кога го напишавме WSDL, во него беа опишани три ентитети за ковертот што влегува во серверот: Барање, Список со поракии порака. Соодветно на часовите Барање, Список со поракии поракасе рефлексии на овие ентитети во нашата PHP скрипта.

Откако ќе ги дефинираме објектите, треба да креираме објект ( $req), кој ќе биде испратен до серверот. Потоа доаѓаат двете најценети линии за нас! Нашиот SOAP клиент! Верувале или не, но ова е доволно за нашиот сервер да почне да истура пораки од клиентот, како и нашиот сервер успешно да ги прима и обработува! Во првиот од нив, создаваме примерок од класата SoapClient и ја пренесуваме адресата на локацијата на датотеката WSDL на нејзиниот конструктор и експлицитно укажуваме во параметрите дека ќе работиме користејќи ја верзијата 1.2 на протоколот SOAP. На следната линија го нарекуваме методот прати СМСобјект $клиенти веднаш прикажете го резултатот во прелистувачот.
Ајде да го извршиме и да видиме што конечно добивме!

Го добив следниов објект од серверот:

Објект(stdClass) јавен „статус“ => бул точно
И ова е прекрасно, затоа што. сега со сигурност знаеме дека нашиот сервер работи и не само што работи, туку може и да врати некои вредности на клиентот!

Сега да го погледнеме дневникот што внимателно го чуваме на страната на серверот! Во првиот дел од него, ги гледаме необработените податоци што влегле во серверот:

79871234567 Тест порака 1 2013-07-21T15:00:00.26 15
Ова е пликот. Сега знаете како изгледа! Но, веројатно нема да бидеме заинтересирани постојано да му се восхитуваме, па ајде да го десериализираме објектот од датотеката за евиденција и да видиме дали сè е во ред со нас:

Object(stdClass) public "messageList" => објект(stdClass) public "message" => објект(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "Test message 1 " (должина=37) јавен „датум“ => низа „2013-07-21T15:00:00.26“ (должина=22) јавен „тип“ => низа „15“ (должина=2)
Како што можете да видите, објектот е правилно десерилизиран, со што би сакал да ни честитам на сите! Следно, не чека нешто поинтересно! Имено, ние ќе испратиме од клиентот до серверот не една смс-порака, туку цел пакет (поточно три цели)!

7 Испраќање сложени објекти

Ајде да размислиме како можеме да испратиме цел куп пораки до серверот во еден пакет? Веројатно најлесниот начин би бил да се организира низа во елементот messageList! Ајде да го направиме тоа:

// креирајте објект за испраќање до серверот $req = new Request(); $req->messageList = нов MessageList(); $msg1 = нова порака(); $msg1->phone = "79871234567"; $msg1->text = "Тест порака 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->тип = 15; $msg2 = нова порака(); $msg2->phone = "79871234567"; $msg2->text = "Тест порака 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->тип = 16; $msg3 = нова порака(); $msg3->phone = "79871234567"; $msg3->text = "Тест порака 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->тип = 17; $req->messageList->порака = $msg1; $req->messageList->порака = $msg2; $req->messageList->порака = $msg3;
Нашите дневници покажуваат дека следниов пакет потекнува од клиентот:

79871234567 Тест порака 1 2013-07-21T15:00:00.26 15 79871234567 Тест порака 2 2014-08-22T16:01:10 16 79871234567 Тест порака 3 2014-08-22T16:01:10 17
Какви глупости, велиш? И ќе бидеш во право во извесна смисла, затоа што. исто како што дознавме дека кој објект го оставил клиентот, тој дојде на нашиот сервер во форма на плик во потполно иста форма. Точно, СМС-пораките не беа серијализирани во XML на начинот на кој ни требаше - тие мораа да бидат завиткани во елементи порака, не е во Структура. Сега да видиме во каква форма таков објект доаѓа до методот прати СМС:

Објект (stdClass) јавен "messageList" => објект (stdClass) јавна "порака" => објект (stdClass) јавен "Struct" => низа (големина=3) 0 => објект (stdClass) јавен "телефон" => низа "79871234567" (должина=11) јавен "текст" => низа "Тест порака 1" (должина=37) јавен "датум" => низа "2013-07-21T15:00:00.26" (должина=22) јавна " тип" => стринг "15" (должина=2) 1 => објект (stdClass) јавен "телефон" => низа "79871234567" (должина=11) јавен "текст" => низа "тест порака 2" (должина= 37) јавен „датум“ => стринг „2014-08-22T16:01:10“ (должина=19) јавен „тип“ => низа „16“ (должина=2) 2 => објект(stdClass) јавен „телефон " => стринг "79871234567" (должина=11) јавен "текст" => низа "Тест порака 3" (должина=37) јавен "датум" => низа "2014-08-22T16:01:10" (должина= 19) јавен „тип“ => низа „17“ (должина=2)
Што ни дава ова знаење? Само што патот што го избравме не е точен и не добивме одговор на прашањето - „Како да ја добиеме правилната структура на податоци на серверот?“. Но, предлагам да не очајуваме и да се обидеме да ја фрлиме нашата низа на типот објект:

$req->messageList->порака = (објект)$req->messageList->порака;
Во овој случај, ќе добиеме уште еден плик:

79871234567 Тест порака 1 2013-07-21T15:00:00.26 15 79871234567 Тест порака 2 2014-08-22T16:01:10 16 79871234567 Тест порака 3 2014-08-22T16:01:10 17
Влезе во методот прати СМСобјектот ја има следната структура:

Објект (stdClass) јавен "messageList" => објект (stdClass) јавна "порака" => објект (stdClass) јавен "BOGUS" => низа (големина=3) 0 => објект (stdClass) јавен "телефон" => низа "79871234567" (должина=11) јавен "текст" => низа "Тест порака 1" (должина=37) јавен "датум" => низа "2013-07-21T15:00:00.26" (должина=22) јавна " тип" => стринг "15" (должина=2) 1 => објект (stdClass) јавен "телефон" => низа "79871234567" (должина=11) јавен "текст" => низа "тест порака 2" (должина= 37) јавен „датум“ => стринг „2014-08-22T16:01:10“ (должина=19) јавен „тип“ => низа „16“ (должина=2) 2 => објект(stdClass) јавен „телефон " => стринг "79871234567" (должина=11) јавен "текст" => низа "Тест порака 3" (должина=37) јавен "датум" => низа "2014-08-22T16:01:10" (должина= 19) јавен „тип“ => низа „17“ (должина=2)
Што се однесува до мене, тогаш „од промена на местата на термините, збирот не се менува“ (в). Што ЛАЖЕН, што СтруктураСè уште не сме ја постигнале целта! А за да го постигнеме, треба да се погрижиме наместо овие неразбирливи имиња, нашиот роден порака. Но, како да се постигне ова, авторот сè уште не знае. Затоа, единственото нешто што можеме да направиме е да се ослободиме од дополнителниот сад. Со други зборови, сега ќе се погрижиме дека наместо поракастана ЛАЖЕН! За да го направите ова, сменете го објектот на следниов начин:

// креирајте објект за испраќање до серверот $req = new Request(); $msg1 = нова порака(); $msg1->phone = "79871234567"; $msg1->text = "Тест порака 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->тип = 15; $msg2 = нова порака(); $msg2->phone = "79871234567"; $msg2->text = "Тест порака 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->тип = 16; $msg3 = нова порака(); $msg3->phone = "79871234567"; $msg3->text = "Тест порака 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->тип = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (објект)$req->messageList;
Што ако имаме среќа и точното име излезе од шемата? За да го направите ова, да го погледнеме пликот што пристигна:

79871234567 Тест порака 1 2013-07-21T15:00:00.26 15 79871234567 Тест порака 2 2014-08-22T16:01:10 16 79871234567 Тест порака 3 2014-08-22T16:01:10 17
Да, чудото не се случи! ЛАЖЕН- Нема да победиме! Влезе прати СМСобјектот во овој случај ќе изгледа вака:

Објект (stdClass) јавен "messageList" => објект (stdClass) јавно "BOGUS" => низа (големина=3) 0 => објект (stdClass) јавен "телефон" => стринг "79871234567" (должина=11) јавна " текст" => стринг „Тест порака 1“ (должина=37) јавен „датум“ => низа „2013-07-21T15:00:00.26“ (должина=22) јавен „тип“ => низа „15“ (должина =2) 1 => објект (stdClass) јавен "телефон" => стринг "79871234567" (должина=11) јавен "текст" => низа "Тест порака 2" (должина=37) јавен "датум" => низа " 2014-08-22T16:01:10" (должина=19) јавен „тип“ => низа „16“ (должина=2) 2 => објект(stdClass) јавен „телефон“ => низа „79871234567“ (должина= 11) јавен „текст“ => стринг „Тест порака 3“ (должина=37) јавен „датум“ => низа „2014-08-22T16:01:10“ (должина=19) јавен „тип“ => низа „ 17" (должина = 2)
Како што велат - „Речиси“! На оваа (малку тажна) белешка, предлагам тивко да заокружиме и да извлечеме некои заклучоци за себе.

8 Заклучок

Конечно стигнавме овде! Ајде да одлучиме што можете да направите сега:
  • можете да ја напишете потребната WSDL датотека за вашата веб-услуга;
  • можете да напишете сопствен клиент без никакви проблеми што може да комуницира со серверот користејќи го протоколот SOAP;
  • можете да напишете свој сервер кој комуницира со надворешниот свет преку SOAP;
  • можете да испраќате низи од ист тип на објекти до серверот од вашиот клиент (со одредени ограничувања).
Исто така, направивме некои откритија за себе за време на нашето мало истражување:
  • матичната класа SoapClient не знае како правилно да ги серијализира структурите на податоци од ист тип во XML;
  • кога се серијализира низа во XML, се создава дополнителен елемент со име Структура;
  • кога се серијализира објект во XML, тој создава дополнителен елемент со име ЛАЖЕН;
  • ЛАЖЕНпомало зло од Структурапоради фактот што пликот е покомпактен (не се додаваат дополнителни именски простори во заглавието на XML на пликот);
  • за жал, класата SoapServer не ги потврдува автоматски податоците од обвивката со нашата XML шема (можеби и другите сервери не го прават тоа).

Што е САПУН?

SOAP кратенка за Simple Object Access Protocol (Simple Object Access Protocol). Се надевам дека откако ќе ја прочитате статијата ќе бидете само збунети: „Како е ова чудно име?

SOAP во неговата сегашна форма е метод за далечинско повикување процедура (RPC) преку мрежа. (Да, исто така се користи за пренесување документи како XML, но засега ќе го прескокнеме.)

Ајде да го сфатиме. Замислете дека имате услуга која враќа понуда за акции за даден тикер (имот на акции). Испраќа податоци до страницата Nasdaq и го генерира посакуваниот резултат врз основа на вратениот HTML. Понатаму, за да им дозволите на другите програмери да ја користат во нивните апликации, ја правите оваа услуга компонента што наоѓа информации за цитати преку Интернет. Работи одлично додека еден ден Nasdaq не го промени изгледот на нивните страници. Мора да ја прегледате целата логика на компонентата и да испратите ажурирања до сите програмери кои ја користат. И тие, пак, треба да испраќаат ажурирања до сите нивни корисници. Ако ова се случува на повеќе или помалку редовна основа, можете да направите многу непријатели меѓу вашите колеги програмери. И кај програмерите, како што знаете, шегите се лоши. Не сакате утре да извадите слика од вашата омилена мачка од канцеларискиот шредер, нели?

Што да се прави? Ајде да видиме... се што ви треба е да обезбедите една функција која ќе земе тикер (од тип стринг) како влез и ќе врати понуда за акции (од тип float или double). Значи, не би било полесно само да им дозволите на вашите програмери некако да ја повикаат оваа функција преку Интернет? Одлично! Тоа е исто така новост за мене, има COM и Corba и Java, кои го прават тоа со години ... она што е вистина е точно, но овие методи не се без недостатоци. Конфигурацијата на далечинскиот COM не е тривијална. Покрај тоа, треба да отворите толку многу порти во заштитниот ѕид што не можете да заштедите доволно пиво за системскиот администратор. Да, и мора да заборавите на корисниците на сите оперативни системи освен Windows. Но, на крајот на краиштата, корисниците на Линукс понекогаш се заинтересирани за размена.

Сепак, сè не е изгубено за корисниците на Linux ако користат DCOM, повеќе овде: http://www.idevresource.com/com/library/res/articles/comonlinux.asp.

Не можам да кажам многу за Corba и Java, па како вежба им предлагам на читателите да ги најдат лошите страни во овие пристапи.

SOAP е стандард кој ви овозможува да опишете таков далечински повик и формата во која резултатот ќе биде вратен. Така, треба да ја хостирате вашата функција во апликација која е достапна преку мрежата и да примате повици во форма на SOAP пакети. После тоа, го потврдувате влезот, ја извршувате вашата функција и го враќате резултатот во нов пакет SOAP. Целиот процес може да работи преку HTTP, така што не мора да отворате куп порти во заштитниот ѕид. Дали е едноставно?

За што е оваа статија

Ова е прва од серијата написи за SOAP што ги пишуваме во Agni Software. Во оваа статија, ќе се обидам да ви дадам идеја за тоа што е SOAP и како да напишете апликација што комуницира со сервер за SOAP.

Сапун и XML

Ако SOAP сè уште ви изгледа едноставен, ајде да додадеме XML. Сега, наместо име на функција и параметри, добиваме прилично сложена XML коверт, како да е дизајнирана да ве збуни. Но, не плашете се. Претстои уште повеќе, а треба да ја видите целата слика за да ја сфатите сложеноста на САПУН.
Ако не знаете што е XML, прво прочитајте ја мојата XML статија овде: http://www.agnisoft.com/white_papers/xml_delphi.asp.

Сите SOAP пакети се во XML формат. Што значи тоа? Ајде да видиме. Погледнете ја оваа функција (Паскал):
функција GetStockQuote(Симбол: низа) : двојно; Изгледа одлично, но проблемот е што тоа е Паскал. Која е употребата на оваа едноставна дефиниција за развивач на Java? Или за некој што работи со VB? Ни треба нешто што секој може да го разбере, дури и VB програмерите. Затоа, дајте им XML што ги содржи истите информации (параметри, берзански понуди, итн.). Вие креирате пакет SOAP, кој во суштина е повик до вашата функција, завиткан во XML, така што секоја апликација на која било платформа може да го разбере. Сега да видиме како изгледа нашиот повик SOAP:
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">


IBM


Информативно, нели? САПУН се поедноставува пред нашите очи. Добро, шегите на страна. Сега ќе се обидам да ви објаснам како да го разберете овој повик SOAP.

Дешифрирање на ознаки

Првата ознака што ви привлекува внимание е . Оваа ознака е надворешната обвивка на пакетот SOAP, која содржи неколку декларации за именски простор кои се од мал интерес за нас, но се многу важни за секој програмски јазик или парсер. Просторите за имиња се дефинирани така што последователните префикси како „SOAP-ENV:“ или „xsd:“ се прифаќаат од страна на анализаторот.

Следната ознака е . (Испуштивме ознака што не е претставена овде - . Не е во овој конкретен пример, но ако сакате да прочитате повеќе за тоа, проверете ја спецификацијата за SOAP овде: http://www.w3.org/TR/SOAP/). Означете всушност содржи повик SOAP.

Следната ознака во листата е − . Името на ознаката, GetStockQuote, е функцијата за повикување. Според терминологијата на SOAP, ова се нарекува операција. Така, GetStockQuote е операцијата што треба да се изврши. ns1 е именскиот простор што укажува на urn:xmethods-quotes во нашиот случај.

Страна забелешка за именските простори: Именскиот простор ви овозможува да се квалификувате XML ознака. Не можете, на пример, да имате две променливи со исто име во иста процедура, но ако тие се во две различни процедури, нема проблем. Така, процедурата е именски простор, бидејќи сите имиња во неа се единствени. Слично на тоа, XML таговите се опфатени во именски простори, па со оглед на именскиот простор и името на ознаката, може уникатно да се идентификуваат. Ќе го дефинираме именскиот простор како URI за да го разликуваме нашиот NS1 од имитаторите. Во примерот погоре, NS1 е псевдоним што покажува на urn:xmethods-quotes.

Забележете го и атрибутот encodingStyle - овој атрибут специфицира како повикот SOAP се серијализира.

Внатре во ознаката содржи параметри. Во нашиот наједноставен случај, имаме само еден параметар - ознаката . Забележете ја оваа линија до ознаката:
xsi:type = "xsd:string"
Ова е приближно како XML ги дефинира типовите. (Забележете колку паметно го користев зборот „приближно“ кога генерализирав за технологијата, што може да се промени откако ќе се објави статијата.) Што точно значи ова: типот дефиниран во именскиот простор xsi, кој забележувате дека е дефиниран во ознаката – xsd:string. И ова, пак, е низа дефинирана во именскиот простор xsd, повторно дефинирана претходно. (Сигурен сум дека адвокатите би биле воодушевени од сето ова).

Внатре во ознаката „IBM“ е наведена. Ова е вредноста на параметарот на симболот на функцијата GetStockQuote.

Па, на крајот, како пристојни луѓе, ги затворивме сите ознаки.

Така, го сфативме пакетот SOAP што го дефинира повикот до серверот SOAP. И серверот SOAP, користејќи XML парсери, црвено копче и вселенската станица MIR, го декодира овој повик и одредува дека ви треба понуда за акции. Веднаш ја наоѓа потребната понуда и ви ја враќа во оваа форма:
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>


34.5


Откако го одвиткавме пликот САПУН, ги скинавме лентите и шушкавме на обвивката, дознаваме дека цената на акцијата на IBM е 34,5.

Повеќето комерцијални сервери би вратиле многу повеќе информации, како на пример во која валута и по која цена е купена последната акција. А цената на акцијата, можеби, би била попрецизна.

На овој начин знаеме што очекува серверот SOAP и што ќе врати. Значи, КАКО ги испраќате овие информации? Може да се користи секаков транспорт. Најосветлен е HTTP. Нема да навлегувам во деталите за HTTP, за оние кои не знаат, тоа е она што го користи вашиот прелистувач за да комуницира со сајтовите што ги посетувате.

Посакуваното HTTP барање би изгледало вака:
POST /StockQuote HTTP/1.1
Домаќин: www.stockquoteserver.com

Содржина-должина: nnnn
SOAPAction: „Some-URI“

Пакетот со барање за сапун овде... Единственото друго нешто што треба да се забележи е заглавието SOAPAction. Ова заглавие ја означува целта на барањето и е потребно. Секој сервер за SOAP може да има неограничен број функции и може да го користи заглавието SOAPAction за да одреди која функција се повикува. Заштитните ѕидови и мултиплексерите исто така можат да ја филтрираат содржината врз основа на ова заглавие.

Одговорот на SOAP од серверот HTTP ќе изгледа вака:
HTTP/1.1 200 ОК
Тип на содржина: текст/xml; charset = "utf-8"
Содржина-должина: nnnn

Пакет за одговор на сапун овде... Зошто HTTP? Прво, мрежните администратори не мора да отвораат многу посебни порти за повици SOAP... веб-серверот може мирно да се справи со повиците, бидејќи Портата 80 обично е отворена за сите за да примаат дојдовни барања. Друга предност е проширливоста на веб-серверите кои користат CGI, ISAPI и други домашни модули. Оваа проширливост ви овозможува да напишете модул што се справува со барањата за SOAP без да влијае на друга веб-содржина.

Тоа е се

Се надевам дека оваа статија помогна да фрли малку светлина врз САПУН. Ако сè уште сте тука и сакате да прочитате повеќе на оваа тема, посетете ја страницата на авторот: http://www.agnisoft.com/soap

Лирски дел.

Замислете дека сте имплементирале или имплементирате одреден систем кој треба да биде достапен однадвор. Оние. има одреден сервер со кој треба да комуницирате. На пример веб-сервер.

Овој сервер може да изврши многу дејства, да работи со базата на податоци, да изврши некои барања од трети страни до други сервери, да прави некои пресметки итн. живеат и евентуално се развиваат според неговото добро познато сценарио (т.е. според сценариото на програмерите). Не е интересно човек да комуницира со таков сервер, затоа што можеби нема да може / не сака да дава убави страници со слики и друга содржина што е погодна за корисниците. Напишано е и работи на работа и издавање податоци на барања за него, без да се грижи дека се читливи за човек, клиентот сам ќе се справи со нив.

Другите системи, кои пристапуваат до овој сервер, веќе можат да располагаат со податоците добиени од овој сервер по сопствена дискреција - обработуваат, акумулираат, издаваат на нивните клиенти итн.

Па, една од опциите за комуникација со такви сервери е SOAP. SOAP XML протокол за пораки.

Практичен дел.

Веб-услугата (тоа е она што го обезбедува серверот и она што го користат клиентите) овозможува да се комуницира со серверот во добро структурирани пораки. Факт е дека веб сервисот не прифаќа никакви податоци. Секоја порака што не се совпаѓа со правилата ќе биде вратена од веб-сервисот со грешка. Грешката ќе биде, патем, и во форма на xml со јасна структура (што не може да се каже точно за текстот на пораката).

WSDL (Јазик на опис на веб-услуги). Правилата со кои се составуваат пораките за веб-услугата се исто така опишани со помош на xml и исто така имаат јасна структура. Оние. ако веб-услугата обезбедува можност за повикување метод, таа мора да им овозможи на клиентите да откријат кои параметри се користат за овој метод. Ако веб-услугата очекува низа за методот Method1 како параметар, а низата мора да се именува Param1, тогаш овие правила ќе бидат наведени во описот на веб-услугата.

Како параметри може да се пренесат не само едноставни типови, туку и објекти, збирки на објекти. Описот на објектот се сведува на описот на секоја компонента на објектот. Ако објектот се состои од неколку полиња, тогаш секое поле е опишано, каков тип има, името (кои се можните вредности). Полињата можат да бидат и од сложен тип и така натаму, додека описот на типовите не заврши со едноставни - стринг, бул, број, датум... Сепак, некои специфични типови може да испаднат едноставни, важно е да клиентите можат да разберат кои вредности можат да бидат содржани во нив.

За клиентите, доволно е да го знаат url-от на веб-услугата, wsdl секогаш ќе биде во близина, со што ќе можете да добиете идеја за методите и нивните параметри што ги обезбедува овој веб-сервис.

Кои се предностите на сите овие ѕвона и свирки:

  • Во повеќето системи, описот на методите и видовите се случува автоматски. Оние. Доволно е програмер на серверот да каже дека овој метод може да се повика преку веб-услуга, а описот на wsdl ќе се генерира автоматски.
  • Описот што има јасна структура е читлив од секој клиент на сапун. Оние. каква и да е веб-услугата, клиентот ќе разбере кои податоци ги прифаќа веб-услугата. Според овој опис, клиентот може да изгради своја внатрешна структура на класи на објекти, т.н. обврзувачки" и. Како резултат на тоа, програмерот што ја користи веб-услугата мора да напише нешто како (псевдокод):

    NewUser:=TSoapUser.Create("Vasya","Pupkin","admin"); сапун.AddUser(NewUser);

  • Автоматска валидација.

    • xml валидација. xml мора да биде добро формиран. неважечки xml - веднаш грешка на клиентот, нека го сфати.
    • валидација на шема. xml мора да има одредена структура. xml не се совпаѓа со шемата - веднаш грешка на клиентот, нека го сфати.
    • валидацијата на податоците ја врши серверот за сапуница, така што типовите на податоци и ограничувањата се совпаѓаат со описот.
  • Овластувањето и автентикацијата може да се имплементираат со посебен метод. природно. или користејќи http авторизација.
  • Веб сервисите можат да работат и преку протоколот за сапун и преку http, односно преку барања за добивање. Односно, ако едноставните податоци (без структура) се користат како параметри, тогаш можете едноставно да го повикате вообичаеното добивање www.site.com/users.asmx/GetUser?Name=Vasia или да објавите. Сепак, ова не е секогаш и секаде.
  • ... види википедија

Има и многу недостатоци:

  • Неразумно голема големина на пораката. Па, овде самата природа на xml е таква што форматот е излишен, колку повеќе ознаки, толку повеќе бескорисни информации. Плус сапунот го зголемува вишокот. За интранет системите, проблемот со сообраќајот е помалку акутен отколку за интернетот, така што сапунот за локални мрежи е повеќе баран, особено, Sharepoint има веб-услуга за сапун со која можете успешно да комуницирате (и некои ограничувања).
  • Автоматската промена на описот на веб-услугите може да ги скрши сите клиенти. Па, тоа е како за секој систем, па ако не е поддржана наназад компатибилноста со старите методи, сè ќе падне ...
  • Не минус, туку недостаток. Сите дејства за повикување на методот мора да бидат атомски. На пример, кога работиме со subd, можеме да започнеме трансакција, да извршиме неколку барања, а потоа да се вратиме назад или да извршиме извршување. Нема трансакции со сапун. Едно барање, еден одговор, муабетот заврши.
  • Справување со описот на она што е на страната на серверот (дали се е опишано правилно од мене?), Што има на клиентот (што ми беше напишано овде?) Може да биде доста тешко. Имаше неколку пати кога морав да се справам со клиентската страна и да го убедам програмерот на серверот дека погрешно ги опишал податоците, но тој воопшто не можеше да разбере ништо во нив, бидејќи автоматското генерирање и тој, како што рече, не требаше, ова е прашање на софтвер. И грешката беше природно во кодот на методот, програмерот едноставно не го виде.
  • Практиката покажува дека развивачите на веб-услуги се ужасно далеку од луѓето што ги користат овие веб-услуги. Како одговор на секое барање (валидно однадвор), може да дојде неразбирлива грешка „Грешка 5. Сè е лошо“. Се зависи од совеста на програмерите :)
  • Сигурен сум дека не се сетив на ништо...

Како пример, постои отворена веб-услуга belavia:

  • http://86.57.245.235/TimeTable/Service.asmx - влезна точка, има и текстуален опис на методите за програмери од трети страни.
  • http://86.57.245.235/TimeTable/Service.asmx?WSDL - wsdl опис на методите и видовите примени и вратени податоци.
  • http://86.57.245.235/TimeTable/Service.asmx?op=GetAirportsList - опис на специфичен метод со пример за типот на xml барање и xml одговор.

Можете рачно да креирате и испратите барање како:

POST /TimeTable/Service.asmx HTTP/1.1 Домаќин: 86.57.245.235 Тип на содржина: текст/xml; charset=utf-8 Содржина-должина: должина SOAPAction: „http://webservices.belavia.by/GetAirportsList“ mk

одговорот ќе биде:

HTTP/1.1 200 OK Датум: понеделник, 30 септември 2013 година 00:06:44 GMT Сервер: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Верзија: 4.0.30319 Кеш-контрола: приватна, макс -age=0 Содржина-Тип: текст/xml; charset=utf-8 Содржина-должина: 2940

ZY Претходно беше отворена веб-услугата на Аерофлот, но откако 1C додаде поддршка за сапун во 8ku, куп 1c бета-тестери успешно го инсталираа. Сега нешто се смени таму (не ја знам адресата, можете да пребарувате ако сте заинтересирани).
ZZY Одрекување. Тој зборуваше на ниво на домаќинство. Можете да пиете.

Во принцип, денес постојат стандардни XML протоколи за размена на податоци:

  • XML-RPC- пренесувате пакет и одредувате кој метод на серверот сакате да го повикате.
  • ОДМОР- има некои објекти на серверот. Секој објект се карактеризира со одреден идентификатор. Секој елемент има своја URL адреса. Со кој било елемент, можете да направите: вметнување, бришење, ажурирање, избирање. Вие едноставно го испраќате посакуваното барање до серверот (на пример, вметнете таков и таков елемент). Размената клиент-сервер се заснова или на JSON или на XML.

SOAP се заснова на RPC (Service Oriented Architecture, збир на лабаво поврзани услуги кои комуницираат едни со други). Главната предност на RPC е малата количина на мрежни ресурси (влезни точки) и многуте вклучени методи. И покрај оваа предност, RPC е застарен протокол кој има голем број на недостатоци:

  • Не можете да ја потврдите пораката XML-RPC. Стариот протокол беше креиран пред шемите (методи за валидација на податоци) да бидат стандардизирани во XML. Оние. серверот прифаќа барања, мора да се погрижи овие барања да се за него и дека податоците не се неконзистентни. Во XML-RPC, типовите на податоци се декларирани за ова, но ова е проверка на типот на податоци, а конзистентноста на податоците не се проверува (дека сте примиле структура со сите потребни параметри).
  • Не можете да креирате комбинирани пораки.
  • Не можете да користите простор и време (се појави по создавањето на RPC).
  • Не можете да ја проширите пораката, т.е. додадете дополнителни информации.

Сите овие недостатоци се решени во XML Шемата. Ова е индустриски стандард за опишување на XML документ. Оние. тоа е начин на моделирање на произволни податоци. XML шемата може да опише модел (односи меѓу елементите и атрибутите и нивната структура), типови на податоци (ги карактеризира типовите на податоци) и вокабулар (имиња на елементи и атрибути).

Врз основа на сите недостатоци на XML-RPC, тие го создадоа протоколот SOAP.

САПУН(Simle Object Access Protocol) - протокол за пристап до објект (влезна точка). Денес тоа е главниот индустриски стандард за градење дистрибуирани апликации.

Тоа е продолжение на јазикот XML-RPC. Оние. тој е изграден на принципот: 1 влезна точка и какви било методи. Самиот протокол во однос на транспортот (како да се префрлат податоци) дава широк избор: SMTP, FTP, HTTP, MSMQ.

SOAP е во срцето на имплементацијата на XML Web Services (XML Web Services). Лошата страна на SOAP е тоа што е тешко да се научи.

SOAP се базира на размена на пораки помеѓу клиентот и серверот (синхроно и асинхроно). Секоја порака носи информации за податоците (кои податоци се пренесуваат/примаат). SOAP однапред ја опишува целата структура на пораката користејќи XML шеми: што треба да има во пораката, како ќе се пренесе. Ова овозможува, без да се знае серверот, да се разбере што се случува таму и му овозможува на серверот да провери дали оваа порака е за него.

XML шема

Целта на шемата е да ја опише структурата на податоците, т.е. она што го имаме. Сите податоци се поделени на едноставни и сложени типови (скалари и структури). Едноставен тип (низа, број, бул, датум) никогаш нема да содржи ништо внатре. Структура (објект) може да содржи својства.

Основни операции со сапун

  • Не само едноставна размена на информации клиент-сервер. Но, автоматското препознавање на серверот и пребарувањето на овој сервер, т.е. клиентот можеби дури и не знае ништо за серверот. Оние. клиентот прво бара сервер, наоѓа соодветни услуги, разбира кои методи постојат, што има на серверот и упатува повик до него.
  • Серверот ги објавува своите информации (локација, кои методи ги поддржува) за да може клиентот да го најде овој сервер. Објавувањето се одвива во директориумот UDDI.

Структура на SOAP пораки:

  • САПУН плик (плик) - ова ја вклучува целата порака. Се состои од заглавие и тело.
  • SOAP Header (заглавие) - дополнителни информации (овластување, на пример).
  • САПУН Тело (тело) - самата порака.
  • SOAP Fault (грешка) - начин за пренос на грешки од серверот на клиентот.

WSDL

WSDL(Јазик на опис на веб услуги) - Јазик за опис на веб услуги. Се користи во САПУН. Ова е еден вид документ кој опишува сè: кои простори со имиња се користени, какви шеми за податоци се користени, какви видови пораки очекува серверот од клиентот, кои пликови припаѓаат на кој метод, кои методи генерално постојат, на која адреса да се испрати, итн. Всушност, WSDL е веб-услуга. Доволно е клиентот да ја проучи содржината на овој документ, тој веќе знае сè за серверот.

Секој сервер треба да го објави WSDL.

WSDL се состои од блокови:

  • Дефиницијата на самата услуга, т.е. влезна точка, пристаништето е наведено.
  • Формат на методот. Влезната точка е врзана за операциите, т.е. кои методи ги поддржува. Наведете го типот на повикот, начинот на пренос. Внатре во секој метод има објаснување - во каква форма се пренесуваат податоците - во форма на САПУН.
  • Методи за врзување на порака.
  • Опис на самите пораки.

Одрекување:Напишани се многу написи на оваа тема и, како што, се разбира, погодивте, ова е уште една. Можеби ќе научите нешто ново од него, но ништо строго доверливо што не би можеле сами да го прогуглате не е опишано овде. Само белешки од лично искуство.

Вовед

Ќе ја разгледаме само ситуацијата кога постои веб-услуга од трета страна и задачата е да се воспостави размена на податоци.

Структурата на услугата е опишана во датотеката WSDL(анг. Јазик на опис на веб-услуги)

Додатотеката најчесто се пристапува преку линк каде што се наоѓа влезната точка на самата веб-услуга. Пишав „најчесто“ затоа што има исклучоци. На пример, веб-услугата базирана на SAP не објавува wsdl и може да се преземе само од самата апликација.

И така, имаме опис на веб-услугата, најава, лозинка. Ајде да се поврземе.

// Дефинирајте ги поставките на URL-то на ServiceNamespace = "http://Somesite.ru"; Корисничко име = "TestUser"; Лозинка = "q1w2e3"; LocationWSDL = "https://Somesite.ru/WebService/Some?wsdl"; ServiceName = "SomeServiceName"; ConnectionPointName = "SomeService_Port"; // Креирај SSL врска = Нова SecureConnectionOpenSSL(); WSDдефиниција = Нова WSDдефиниција (ЛокацијаWSDL,SSL); WSProxy = Нов WSPProxy (WSDдефиниција, URL-адреса за име на услуга, име на услуга, ConnectionPointName, SSL); WSProxy.User = Корисничко име; WSProxy.Password = Лозинка;

Одлично! Се поврзавме на веб-услугата! Во теорија, ова е основата на секоја опција за размена, бидејќи ви овозможува да креирате објект на структура на податоцибазирана на wsdl, а работата со таков објект е задоволство.

Размислете за XML што ни го дава SoapUI

357 121212 М 19900111 Мерцедес GLS Ауди ТТ

Сега да го опишеме програмски

// Направете објект и пополнете го со податоци OwnXDTOFactory = WSDefinition.XDTOFactory; RootType = OwnFactoryXDTO.Type(URLServiceNamespace, "SUBMISSION"); RootObject = OwnFactoryXDTO.Create(RootType); RootObject.ID = "4356"; ClientType = OwnFactoryXDTO.Type (URLServiceNamespace, „CUSTOMER“); ClientObject = OwnFactoryXDTO.Create(ClientType); ClientObject.CLIENT_ID = "121212"; ClientObject.SEX = "М"; // F - женски, M - машки ClientObject.CLIENT_BIRTHDAY = "19900111"; // Customer Cars AutoType = CustomFactoryXDTO.Type (URLServiceNamespace, "CARS"); AutoObject = OwnFactoryXDTO.Create(AutoType); AutoObject.CLASS = „Мерцедес“; AutoObject.MODEL = "GLS"; ClientObject.CARS.Add(AutoObject); AutoObject = OwnFactoryXDTO.Create(AutoType); AutoObject.CLASS = "Audi"; AutoObject.MODEL = "TT"; ClientObject.CARS.Add(AutoObject); RootObject.CUSTOMER.Add(ClientObject);

Податоците се успешно завршени. Сега треба да ги испратиме.

Токму во овој момент се појавуваат многу нијанси. Ајде да се обидеме да го разгледаме секој.

Рецепт 1. Испраќање на целиот објект XDTO

Резултат = WSProxy.AddCustomers(RootObject);

Останува само да го обработиме резултатот што ни го врати услугата и тоа е тоа. Се согласувам дека е многу погодно!

Но, во пракса тоа не е секогаш случај. На пример, 1c не се согласува со префиксирање на одредени ознаки во xml кога именскиот простор на коренската ознака се разликува од оној на детските ознаки. Во такви случаи, мора рачно да собирате сапун. Морав да се занимавам и со веб сервиси кои очекуваат чист xml како параметар. Лудило, но сепак не е премногу тешко да се направи.

Рецепт 2. Испраќање на чист xml како параметар

XMLRecordParameters = NewXMLRecordParameters("UTF-8", "1.0", True); MyXML = Нов XMLWriter; MyXML.SetString(XMLRecordParameters); MyXML.WriteDeclarationXML(); CustomXDTOFactory.WriteXML(MyXML, RootObject); StringXML = MyXML.Close(); Ако DeleteNamespaceDescription Потоа AttemptFirstTagInString = StrGetString(XMLString,2); RootTagName = RootObject.Type().Име; XMLString = StrReplace(XMLString, FirstTagInString, "<"+ИмяКорневогоТэга+">"); Исклучок //ErrorDescription() EndTry; EndIf; Result = WSPProxy.AddCustomers (XML String);

Ако не го отстраните именскиот простор што 1s го додава стандардно, тогаш тој стана повеќе од само 5 линии код. Најчесто, трансформацијата xml ја завиткам во функција, бидејќи обично повикуваме повеќе од еден метод.

Рецепт 3. Испратете преку мајчин барање HTTP.

Низа САПУН = " | | |" +StringXML+" | |"; // Опишување на заглавијата на барањата HTTP Headers = Ново совпаѓање; Headers.Insert("Content-Type", "text/xml;charset=UTF-8"); Headers.Insert("SOAPAction", "http:// sap .com/xi/WebService/soap1.1"); Headers.Insert("Овластување", "Основно "+GetBase64AuthorizationHeader(Корисничко име, лозинка)); // ВНИМАНИЕ!!! // Не можете програмски да ги пополните следните заглавија, бидејќи ова води до грешка // Платформата ќе ги пополни правилно //Headers.Insert("Accept-Encoding", "gzip,deflate"); //Headers.Insert("Content-Length", Format(StringLength( SOAP String)," HG=")); // должина на пораката //Headers.Insert("Host", "Somesite.ru:8001"); //Headers.Insert("Connection", "Keep-Alive") ; //Заглавија. Вметнете ("Корисник-агент", "Apache-HttpClient/4.1.1 (java 1.5)"); // Поврзете се на страницата. Врска = Нова HTTPConnection ("Somesite.ru/WebService/Some", Корисничко име, лозинка, SSL, неточно); // Адресата мора да биде без https:// // Добијте го текстот на основната страница преку барање POST. c = Ново HTTPRequest("/GetCustomer", Заглавија); HTTPRequest.SetBodyFromString(SOAPString); Резултат = Connection.CallHTTPMmethod("POST", HTTPRequest);

Во оваа опција, ќе треба рачно да изградиме сапун. Во суштина, ние едноставно го завиткуваме xml од рецептот 2 во обвивка за сапун, каде што, во зависност од барањата на веб-услугата, можеме да го смениме нашиот сапун до содржината на нашата душа.

Следно, ги опишуваме заглавјата според документацијата. Некои услуги лесно ќе го џвакаат нашето барање без заглавија, тука треба да погледнете конкретен случај. Ако не знаете кои заглавија да препишете, тогаш најлесниот начин е да го погледнете барањето во SoapUI со префрлување на картичката RAW.

Функцијата за добивање на низата Base64 изгледа вака (ѕирна):

Функција GetBase64AuthorizationHeader(Корисничко име, лозинка) FileEncoding = TextEncoding.UTF8; TempFile = GetTemporaryFileName(); Record = New TextWrite (TemporaryFile, FileEncoding); Write.Write(Корисничко име+":"+Лозинка); Record.Close(); BinData = Нови бинарни податоци (TempFile); Резултат = Base64String (DvData); DeleteFiles (TempFile); Резултат = Средно (резултат,5); Резултат на враќање; Крај Функции

Постои важна точка. Кога работите со HTTPConnection, наведете ја адресата без да ги наведете протоколите „http://“ и „https://“, во спротивно ризикувате да губите време барајќи неочигледна грешка.

Рецепт 4. Испраќање преку WinHttpRequest

WinHttp = Нов COMObject ("WinHttp.WinHttpRequest.5.1"); WinHttp.Option (2"UTF-8"); WinHttp.Option(4, 13056); //intSslErrorIgnoreFlag WinHttp.Option(6, true); //blnEnableRedirects WinHttp.Option(12, true); //blnEnableHttpsToHttpПренасочува WinHttp.Open("POST", "https://Somesite.ru/WebService/Some/GetCustomer", 0); WinHttp.SetRequestHeader ("Тип на содржина", "текст/xml"); WinHttp.SetCredentials (Корисничко име, лозинка, 0); WinHttp.Send(SOAP String); WinHttp.WaitForResponse(15); XMLResponse = WinHttp.ResponseText();

Тука, всушност, исто како и во претходната верзија, но работиме со COMOобјект. Ние ја одредуваме низата за поврзување во целост, заедно со протоколот. Посебно внимание треба да се посвети само на знаменцата за игнорирање на грешки во SSL сертификатите. Тие се потребни ако работиме преку SSL, но без специфичен сертификат, бидејќи не е можно да се создаде нова безбедна врска во оваа опција (или не знам како). Остатокот од механизмот е сличен на претходниот.

Исто така, покрај „WinHttp.WinHttpRequest.5.1“, можете да користите „Microsoft.XMLHTTP“, „Msxml2.XMLHTTP“, „Msxml2.XMLHTTP.3.0“, „Msxml2.XMLHTTP.6.0“, ако одеднаш не потрае исклучено на WinHttp. Методите се речиси исти, само бројот на параметри е различен. Се сомневам дека една од овие опции е поврзана во објектот 1c HTTPRequest.

Во моментов, ова се сите рецепти што ги имам. Ако наидам на нови, дефинитивно ќе ја дополнам статијата.

Обработка на резултати

Во рецептот 1, најчесто добиваме готов објект XDTO и работиме со него како структура. Во сите други случаи, можете да го конвертирате xml одговорот во XDTO

Ако Result.StatusCode = 200 Потоа XMLReader = Нов XMLReader; ReadingXML.SetString(Result.GetBodyAsString()); ResponseObject = OwnFactoryXDTO.ReadXML(ReadingXML); Извештај (ObjectResponse.Body.Response.RESPONSE_ID); Извештај (ObjectResponse.Body.Response.RESPONSE_TEXT); EndIf;

Сè е едноставно овде.

Наместо заклучок

1. Започнете да работите со веб-услуги со програмата SoapUI. Тој е дизајниран за таква работа и ќе ви овозможи брзо да разберете како функционира одредена услуга. Има статија за учење

2. Ако се разменувате со услуга преку несигурен http канал и се поставува прашањето што точно испраќа 1s во вашите пораки, тогаш можете да користите сообраќајни трагачи како што се Wireshark, Fiddler и други. Проблемот се јавува само ако користите ssl конекција.

3. Ако, сепак, веб-услугата комуницира преку https, тогаш го инсталираме серверот Nginx на оддалечена машина (било која, што е најважно, не на наша страна), со која ќе контактираме, а тој, пак, ќе спакува сè во https и испратете го на вистинското место (обратен прокси ) и додадете во стандардната конфигурација:

Сервер (слушајте 0.0.0.0:8080; име на серверот MyServer; локација ~ .* ( proxy_pass https://Somesite.ru:8001; proxy_set_header Домаќин $домаќин; proxy_set_header Овластување „Основно "; proxy_pass_header Овластување; ) )

5. Ако автентикацијата вклучува употреба на колачиња, тогаш е пронајдено следново

П.С. Ако имате прашања, предлози за подобрување на кодот, имате свои рецепти кои се разликуваат од опишаните, наоѓате грешки или мислите дека авторот „греши“ и дека „не спаѓа во 1-ви“, тогаш напишете коментари и ќе разговараме сè.