Какво е SOAP? Какво ще кажете за IBM SOAP4J

Какво е SOAP? Какво ще кажете за IBM SOAP4J

Брет Маклафлин Превод на Иля Чекменев

SOAP е прост протокол за достъп до обекти. Ако никога преди не сте чували за това, значи трябва да живеете в средата на нищото, далеч от цивилизацията. Стана най-новата мода в уеб програмирането и неразделна част от уеб услугите, които се използват с такъв фанатизъм в уеб разработките от последно поколение. Ако сте чували за .NET на Microsoft, или peer-to-peer „революция“, значи сте чували за технологии, които разчитат на SOAP (дори и да не знаете какво представлява). Няма нито едно, но двеИмплементации на SOAP от Apache и Microsoft, които имат хиляди страници, посветени на тях на своя сайт за поддръжка на MSDN (http://msdn.microsoft.com/).

В тази статия ще ви разкажа какво е SOAP и защо е толкова важна част от развитието на парадигмата на уеб програмирането. Това ще ви помогне да пропуснете основите и да започнете направо работа със SOAP инструментариума. След това ще направя бърз преглед на съществуващите SOAP проекти и ще се потопя в имплементацията на Apache. Тази статия няма за цел да предостави пълна картина на SOAP; моята книга, Java & XML, 2-ро издание, запълва много от пропуските. В книгата ще намерите отговори на много от въпросите, възникнали след прочита на тази статия.

Въведение

Първо трябва да разберете какво е SOAP. Можете да прочетете пълното (и доста дълго) становище на W3C на http://www.w3.org/TR/SOAP. Тогава, след като го разберете и изхвърлите цялата обвивка, ще разберете, че SOAP е просто протокол. Това е прост протокол (няма нужда да пишете нов, за да го използвате), базиран на идеята, че в даден момент от разпределената архитектура има нужда от обмен на информация. В допълнение, за системи, в които има възможност за претоварване и затруднения в процесите на обработка, този протокол е много изгоден с това, че е лек и изисква минимално количество ресурси. И накрая, той позволява всички операции да се извършват през HTTP, което прави възможно да заобиколите такива трудни неща като защитни стени и да се предпазите от прослушване чрез сокети на невероятен брой портове. Основното е да осъзнаете това, а всичко останало са подробности.

Разбира се, бихте искали да знаете тези подробности и аз няма да ги пренебрегна. Има три основни компонента на SOAP спецификацията: SOAP обвивка, набор от правила за криптиране и средство за взаимодействие между заявката и отговора. Нека си представим едно SOAP съобщение като обикновено писмо. Помните ли още онези старинни неща в пликове с пощенска марка и адрес, написан отпред? Тази аналогия ще ви помогне да разберете по-ясно концепцията за SOAP като "плик". Фигура 12-1 изобразява SOAP процесите под формата на тази аналогия.

Фигура 12-1. SOAP процес на съобщения

Запомнете тази картина и нека да разгледаме трите компонента на SOAP спецификацията. Ще говоря накратко за всеки от тях, като дам примери, които най-добре представят концепцията. Тези три ключови компонента правят SOAP толкова важен и значим. Обработката на грешки, поддръжката на различни криптирания, сериализацията на параметри и фактът, че SOAP работи през HTTP в повечето случаи го правят по-привлекателен от други решения за разпределени протоколи. SOAP осигурява висока степен на оперативна съвместимост с други приложения, които разгледах по-подробно в моята книга. Засега искам да се съсредоточа върху основните елементи на SOAP.

Плик

SOAP пликът е подобен на обикновения плик за писмо. Той съдържа информация за съобщението, което ще бъде криптирано в главната SOAP секция, включително информация за получателя и подателя, както и информация за самото съобщение. Например заглавката на SOAP плика може да показва как трябва да се обработи съобщението. Преди приложението да започне да обработва съобщение, то проверява информацията за съобщението, включително дали изобщо може да го обработи. За разлика от ситуацията със стандартните XML-RPC извиквания (помните ли? XML-RPC съобщения, криптиране и т.н., всичко се комбинира в един XML фрагмент), при SOAP текущата обработка се извършва, за да се научи нещо за съобщението. Типично SOAP съобщение може също да включва стил на криптиране, който ще помогне на получателя при обработката на съобщението. Пример 12-1 демонстрира SOAP плик, който завършва със спецификация за кодиране.

Пример 12-1: SOAP плик

Сапунерка http://www-106.ibm.com/developerworks/library/x-soapbx1.html

Както можете да видите, криптирането е посочено вътре в плика, което позволява на приложението да определи (използвайки стойността на атрибута encodingStyle), дали може да прочете входящото съобщение, намиращо се в елемента Тяло. Уверете се, че пространството на имената на SOAP плика е правилно, или SOAP сървърите, които получават вашето съобщение, ще докладват грешка при несъответствие на версията и няма да можете да комуникирате с тях.

Шифроване

Вторият важен елемент на SOAP е възможността за криптиране на потребителски типове данни. С RPC (и XML-RPC), криптирането може да се извърши само върху предварително дефинирани типове данни, които се поддържат в XML-RPC инструментариума, който сте изтеглили. Шифроването на други типове данни изисква сами да промените RPC сървъра и клиента. Със SOAP една XML схема може да се използва доста лесно за указване на нови типове данни (използвайки структурата комплексен тип, обсъдено в Глава 2 на моята книга), и тези нови типове могат да бъдат представени в XML като част от основния раздел на SOAP. Благодарение на интегрирането на XML Schema можете да шифровате всякакъв тип данни в SOAP съобщение, като ги опишете логически в XML Schema.

Обадете се

Най-добрият начин да разберете как работи едно SOAP повикване е да го сравните с нещо, с което сте запознати, като например XML-RPC. Ако си спомняте, извикването на XML-RPC изглежда подобно на кодовия фрагмент, представен в пример 12-2.

Пример 12-2. Обадете се на XML-RPC

// Указване на XML процесора (парсер) за използване на XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser"); // Указване на сървъра, към който се осъществява връзката XmlRpcClient client = new XmlRpcClient("http://rpc.middleearth.com"); // Създаване на параметри Vector params = new Vector(); params.addElement(flightNumber); params.addElement(numSeats); params.addElement(creditCardType); params.addElement(creditCardNum); // Заявка Boolean buyTickets = (Boolean)client.execute("ticketCounter.buyTickets", params); // Обработка на отговора

Създадох проста програма за поръчка на самолетни билети. Сега погледнете Пример 12-3, който демонстрира SOAP повикване.

Пример 12-3. Обадете се на SOAP

// Създаване на параметри Vector params = new Vector(); params.addElement(нов параметър("flightNumber", Integer.class, flightNumber, null)); params.addElement(нов параметър("numSeats", Integer.class, numSeats, null)); params.addElement(нов параметър("creditCardType", String.class, creditCardType, null)); params.addElement(нов параметър("creditCardNumber", Long.class, creditCardNum, null)); // Създаване на Call обект Call call = new Call(); call.setTargetObjectURI("urn:xmltoday-airline-tickets"); call.setMethodName("buyTickets"); call.setEncodingStyleURI(Константи.NS_URI_SOAP_ENC); call.setParams(params); // Отговор на повикване res = call.invoke(нов URL("http://rpc.middleearth.com"), ""); // Обработка на отговора

Както можете да видите, действителното повикване, представено от обекта Обадете се, резидент на паметта. Той ви позволява да посочите целта на повикването, метода на повикване, стила на криптиране, параметрите и много други параметри, които не са представени в този пример. Това е по-гъвкав механизъм от метода XML-RPC, който ви позволява изрично да посочите набор от различни параметри, които са имплицитно дефинирани в XML-RPC. По-късно в тази статия ще научите повече за процеса на повикване, включително как SOAP обработва невалидни заявки, йерархията на грешките и, разбира се, върнатите резултати от повикванията.

След такова кратко въведение вече знаете достатъчно, за да се интересувате от това смешно нещо. Сега позволете ми да ви запозная с изпълнението на SOAP, което ще използвам. Ще обясня причините, поради които го избрах, и ще разгледам някои примерни кодове.

Настройки

Сега, след като научихте основите на концепцията, е време за забавната част: програмирането. За да направите това, ще ви трябва удобен проект или продукт, който е по-лесен за намиране, отколкото може да изглежда на пръв поглед. Ако имате нужда от Java проект, който предоставя SOAP възможности, не е нужно да търсите дълго, за да намерите такъв. Има две групи продукти: търговски и безплатни. Както и в моята книга, ще избягвам да споменавам търговски продукти. Това съвсем не е защото са лоши (напротив, някои от тях са отлични), а защото бих искал всеки читател да може да изпробва някой от дадените примери. Това се дължи на достъпността, която много търговски продукти нямат. Трябва да платите, за да ги използвате, или да ги използвате временно за ограничен период от време след изтеглянето.

Така плавно се приближихме към проекти с отворен код. От тази област мога да назова само един продукт: Apache SOAP. Той се намира на http://xml.apache.org/soap и предоставя SOAP инструментариум за Java. Към момента на писане беше пусната версия 2.2, която можете да изтеглите от уебсайта на Apache. Именно тази версия ще използвам в примерите за тази статия.

Други алтернативи

Преди да премина към инсталиране и конфигуриране на Apache SOAP, ще отговоря на няколко въпроса, които може да са се прокраднали в ума ви. Мисля, че обясних доста ясно причините, поради които не използвам търговски продукти. Възможно е обаче да мислите за някои други проекти с отворен код или сродни проекти, които бихте искали да използвате, и сте изненадани, че не съм ги коментирал.

Какво ще кажете за IBM SOAP4J?

Първата в списъка с алтернативи е реализация от IBM: SOAP4J. Работата на IBM формира основата на проекта Apache SOAP, точно както XML4J на IBM прерасна в това, което сега е известно като проект за анализатор на XML Apache Xerces. Предполага се, че изпълнението на IBM ще бъде преработено, сливайки се с Apache SOAP. Почти същото се случи с XML4J на IBM: сега той предоставя само пакетиране в Xerces. Това само подчертава тенденциите - големите производители често поддържат и използват OpenSource проекти, в този случай и двата проекта (Apache и IBM) използват една и съща кодова база.

Microsoft извън играта ли е?

Разбира се, че не. Microsoft и нейната SOAP реализация, както и цялото .NET движение (обсъдено по-подробно в моята книга), са доста значими. Наистина исках да прекарам по-голямата част от времето си в подробно разглеждане на SOAP изпълнението на Microsoft, но то поддържа само COM обекти и не поддържа Java. Поради тези причини такова описание не може да бъде включено в статия за Java и XML. Microsoft обаче (въпреки всички оплаквания, които ние, като разработчици, имаме към тази компания) свърши важна работа в областта на уеб услугите и ще направите грешка, ако я отхвърлите без да се замислите, водени само от сурови емоции. Ако имате нужда да работите с компоненти COM или Visual Basic, горещо ви препоръчвам да опитате да използвате набора от инструменти SOAP на Microsoft, достъпен на http://msdn.microsoft.com/library/default.asp?url=/nhp/Default .asp ?contentid=28000523 заедно с много други SOAP ресурси.

Какво е Axis?

Тези от вас, които следят дейностите на Apache, трябва да са чували за Apache Axis. Axis е SOAP инструментариум от следващо поколение, също разработен под егидата на Apache XML. SOAP (спецификация, а не конкретна реализация), който напоследък се развива бързо и радикално, е много труден за следване. Опитът да се създаде версия на SOAP, която напълно отговаря на текущите изисквания, докато се развиват, също е доста предизвикателство. В резултат на това настоящата версия на Apache SOAP предлага решение, ограничено от своя дизайн. След като решиха, че не си струва да се опитват напълно да преработят съществуващия инструмент, разработчиците на Apache започнаха да създават проект, базиран на новия код. Така се роди Axis. Името на SOAP също се промени, първо от SOAP на XP и след това на XMLP. След това името на спецификацията беше премахнато от името на новия SOAP и се роди името "Axis". Но сега изглежда, че W3C се връща към името на SOAP спецификацията (версия 1.2 или 2.0), така че нещата все още могат да се променят и ще има още повече объркване!

Мислете за IBM SOAP4J като за архитектура?1 на SOAP инструментариума. Какво ще кажете за Apache SOAP (обсъден в тази статия) като архитектура? 2. А Axis представлява архитектурата ?3, архитектура от ново поколение. Този проект използва SAX, докато Apache SOAP е базиран на DOM. В допълнение, Axis, за разлика от Apache SOAP, предоставя по-лесен за потребителя подход за взаимодействие с потребителя. След като изброих тези предимства, може би се чудите защо не избрах Axis като предмет на изследване. Просто би било малко преждевременно. В момента само версия 0.51 на Axis се подготвя за пускане. Това все още не е бета или дори алфа версия. Бих искал да говоря за новите функции на Axis, но няма да имате шанс да убедите ръководството си, че можете да използвате суб-алфа софтуер с отворен код за вашите критични системни нужди. Затова реших да се съсредоточа върху нещо, което вие сте истински можеш да използвашвече Днес- Apache SOAP. Мисля, че докато бъде пусната окончателната версия на Apache Axis, ще актуализирам този материал в следващото издание на моята книга. Дотогава нека се съсредоточим върху решението, което вече е налично.

Инсталация

Има две възможни форми на инсталиране на SOAP. Първият е да стартирате SOAP клиент, използвайки SOAP API, за да комуникирате със сървър, който може да приема SOAP съобщения. Вторият начин е да стартирате SOAP сървър, който може да получава съобщения от SOAP клиент. В този раздел описах и двете процедури.

Клиент

За да използвате SOAP клиента, трябва първо да изтеглите Apache SOAP, наличен на http://xml.apache.org/dist/soap. Изтеглих версия 2.2 в двоичен формат (от поддиректорията версия-2.2). След това трябва да разархивирате съдържанието на архива в директория на вашия компютър. В моя случай това беше директорията javaxml2 (c:\javaxml2на моя компютър с Windows /javaxml2на моя компютър с Mac OS X). В резултат на това файловете бяха разархивирани в /javaxml2/сапун-2_2. Вие също ще трябва да изтеглите пакета JavaMail, достъпен от Sun http://java.sun.com/products/javamail/. Ще се изисква да поддържа SMTP протокола за прехвърляне, използван от Apache SOAP. След това изтеглете Java Beans Activation Framework (JAF), достъпен също от Sun http://java.sun.com/products/beans/glasgow/jaf.html. Въз основа на предположението, че вече имате Xerces или друг XML анализатор, инсталиран и готов за използване.

Забележка:Уверете се, че вашият XML анализатор е съвместим с JAXP и използва правилно пространството от имена. Вашият анализатор най-вероятно отговаря на тези изисквания. Ако имате проблеми, най-добре е да се върнете към използването на Xerces.

Забележка:Използвайте най-новите версии на Xerces. Версия 1.4 и по-нова ще свърши работа. Има редица грешки при SOAP и Xerces 1.3(.1), така че съветвам да не използвате тази комбинация.

Разархивирайте пакетите JavaMail и JAF и след това включете техните jar файлове във вашия класов път, както и библиотеката сапун.буркан. Всеки от тези jar файлове трябва да се намира или в основната директория на съответната програма, или в поддиректория /lib. Когато приключите, вашата променлива клас пъттрябва да изглежда нещо подобно:

$ 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

За Windows ще изглежда така:

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

И накрая добавете директорията javaxml2/сапун-2_2/във вашия клас пътза изпълнение на SOAP примери. Описах настройката за няколко примера в тази глава.

сървър

За да създадете SOAP-съвместим набор от сървърни компоненти, първо се нуждаете от servlet engine. Както в предишните глави, използвах Apache Tomcat (наличен на http://jakarta.apache.org/) като пример за тази глава. Ще трябва да добавите всичко необходимо на клиента клас пътсървър. Най-лесният начин да направите това е да нулирате сапун.буркан, activation.jarИ mail.jar, както и вашия анализатор, в директорията с библиотеки на вашата сървлет машина. За Tomcat това е директорията /lib, която съдържа библиотеки за автоматично зареждане. Ако искате да предоставите поддръжка за скриптове (които не се обсъждат в тази глава, но са в примерите за Apache SOAP), трябва да поставите bsf.jar(достъпно на http://oss.software.ibm.com/developerworks/projects/bsf) и js.jar(наличен на http://www.mozilla.org/rhino/) в същата директория.

Забележка:Ако използвате Xerces с Tomcat, ще трябва да повторите трика, който разгледах в Глава 10. Преименуване parser.jar V z_parser.jar, А jaxp.jar V z_jaxp.jarза да се уверите, че xerces.jarи включената версия на JAXP се зарежда преди всеки друг парсер или реализация на JAXP.

След това рестартирайте вашата сървлет машина, след което сте готови да пишете компоненти на SOAP сървъра.

Router Servlet и Admin Client

Освен основните операции, Apache SOAP включва сървлет на рутер, както и администраторски клиент. Дори и да не възнамерявате да ги използвате, препоръчвам ви да ги инсталирате, за да проверите дали SOAP е инсталиран правилно. Този процес зависи от това коя сървлет машина използвате, така че ще огранича инсталационния процес до Tomcat. Инструкции за инсталиране на някои други сървлет машини могат да бъдат намерени на http://xml.apache.org/soap/docs/index.html.

Инсталирането под Tomcat е много просто: просто вземете файла сапун.войнаот директория сапун-2_2/webappsи го пуснете в директорията $TOMCAT_HOME/webapps- и това е! За да проверите инсталацията, въведете адреса в браузъра си http://localhost:8080/soap/servlet/rpcrouter. Трябва да получите отговор, подобен на показания на Фигура 12-2.

Фигура 12-2. Рутер RPC сервлет

Въпреки че съобщението изглежда като съобщение за грешка, то показва, че всичко работи правилно. Трябва да получите същия отговор, ако насочите браузъра си към клиентския адрес на администратора: http://localhost:8080/soap/servlet/messagerouter.

За да завършите тестването на сървъра и клиента, уверете се, че сте изпълнили всички инструкции напълно. След това изпълнете следния Java клас, както е показано по-долу, за да поддържате URL адреса на вашия сървлет за сървлета на RPC рутера:

C:\>java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter списък Разположени услуги:

Трябва да получите празен списък с услуги, както е показано по-горе. Ако получите някакви съобщения, моля, прегледайте дългия списък с възможни грешки, достъпен на http://xml.apache.org/soap/docs/trouble/index.html. Това е най-изчерпателният списък с проблеми, които може да срещнете. Ако получите празен списък, това означава, че настройката е завършена и сте готови да започнете да разглеждате примерите, дадени в тази глава.

Да започваме

Има три основни етапа при писането на всяка SOAP-базирана система. След като ги изброих, ще се спра накратко на всеки от тях:

  • Избор между SOAP-RPC и SOAP съобщения;
  • Писане или получаване на достъп до SOAP услуга;
  • Писане или достъп до SOAP клиент.

Първата стъпка е да изберете дали ще използвате SOAP за RPC повиквания (при които отдалечена процедура се изпълнява на сървъра) или съобщения (при които клиентът просто изпраща части от информация до сървъра). Обсъждам тези процеси подробно по-долу. След като вземете това решение, ще трябва да получите достъп или да създадете своя собствена услуга. Разбира се, тъй като всички сме професионалисти в Java, тази глава описва как да създадете свой собствен. И накрая, трябва да напишете клиент за тази услуга, това е всичко!

RPC или съобщения?

Първата ви задача няма нищо общо с програмирането и е по-скоро дизайнерско естество. Трябва да изберете дали ще използвате RPC или услуга за съобщения. Ще приемем, че сте запознати с RPC (например, като прочетете една от главите на моята книга). Клиентът изпълнява отдалечена процедура на сървъра и след това получава отговор. В този сценарий SOAP действа като подобрена XML-RPC система, която осигурява по-добра обработка на грешки и прехвърляне на сложни типове данни по мрежата. Вече сте запознати с тази концепция и тъй като RPC системите са по-лесни за писане в SOAP, ще започна с тях. Тази статия описва как да създадете RPC услуга, RPC клиент и да приведете системата в действие.

Друг начин на работа на SOAP е базиран на обмен на съобщения. Вместо да извършва дистанционни процедури, той се използва само за обмен на информация. Както можете да се досетите, това е мощен инструмент, който не изисква от клиента да познава отделните методи на всеки сървър. Той също така прави моделирането на отдалечени системи по-изолирано, като позволява пакети с данни (пакети в преносен смисъл, не в мрежов смисъл) да бъдат изпращани до други системи. В същото време другите системи не трябва да знаят за операциите, извършени с тези данни. Този стил е по-сложен от RPC програмирането, така че няма да го описвам тук. Ще го намерите в моята книга, заедно с други подробности за взаимодействието между бизнеси. Първо, запознайте се с програмирането на SOAP-RPC.

Като повечето дизайнерски проблеми, вземането на това решение зависи от вас. Анализирайте вашето приложение и се опитайте да определите защо трябва да използвате SOAP. Ако имате сървър и набор от клиенти, които изпълняват специфични бизнес функции при поискване, тогава RPC е по-подходящ за вас. В сложни системи, в които обменът на данни е нещо повече от просто изпълнение на специфични бизнес функции при поискване, използването на SOAP съобщения е много за предпочитане.

RPC услуга

След като формалностите приключиха, време е да действаме. Както знаете, в RPC ще ви трябват класове, чиито методи ще се изпълняват дистанционно.

Кодови фрагменти

Ще започна, като разгледам някои кодови фрагменти за сървъра. Тези фрагменти са класове с методи, които се изпълняват за RPC клиенти. Използвах код от моята книга като примери. Вместо да използвам прости класове, избрах по-сложен пример, за да демонстрирам възможно най-ясно възможностите на SOAP. И така, използвах класа CD като пример. Първо дефинираме елемента картаза всеки тип нестандартен параметър. За атрибут encodingStyle, поне в Apache SOAP 2.2. трябва да предоставите стойността http://schemas.xmlsoap.org/soap/encoding/ . В момента това е единственото поддържано кодиране. Трябва да укажете пространството от имена за дефинирания от потребителя тип и след това името на класа с префикс пространство от имена за този тип. В нашия случай за тези цели използвах фиктивно пространство от имена и прост префикс " х". След това с помощта на атрибута javaType, задайте истинското име на Java класа (за този случай - javaxml2.CD). И накрая, kuralesil с атрибути java2XMLClassNameИ xml2JavaClassName. С тяхна помощ се посочва клас, който се конвертира от Java в XML и обратно. Използвах невероятно удобния клас BeanSerializer, също включен в Apache SOAP. Ако вашият персонализиран параметър е във формат JavaBean, този сериализатор и десериализатор ще ви спести необходимостта да пишете свой собствен. Имате нужда от клас с конструктор по подразбиране (не забравяйте, че за CD класа дефинирах прост конструктор без параметри) и публикувайте всички данни от този клас, като използвате методи setXXXИ getXXX. Защото класа CDнапълно отговаря на всички тези изисквания, BeanSerializerработи перфектно.

Забележка:Какъв клас CDотговаря на изискванията BeanSerializer. няма голямо значение. Повечето класове лесно се конвертират в този формат. Затова ви съветвам да избягвате да пишете свои собствени сериализатори и десериализатори. Това е допълнително главоболие (нищо сложно, но твърде старателно) и ви препоръчвам да пестите енергията си и да използвате bean преобразуване във вашите потребителски параметри. В много случаи преобразуването на bean изисква само конструктор по подразбиране (без параметри) във вашия клас.

Сега нека пресъздадем бурканфайл и преинсталирайте нашата услуга:

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

Внимание:Ако оставите сървлет машината да работи и прехоствате услуга едновременно, ще трябва да рестартирате сървлет машината, за да активирате новите класове за SOAP услугата и да хоствате повторно услугата.

Сега всичко, което остава, е да модифицираме клиента да използва нови класове и методи. Пример 12-10 съдържа модифицирана версия на клиентския клас CDAdder. Промените, направени в предишната версия, са маркирани.

Пример 12-10: Актуализиран клас CDAdder

пакет javaxml2; импортиране на java.net.URL; импортиране на java.util.Vector; импортиране на org.apache.soap.Constants; импортиране на org.apache.soap.Fault; импортиране на org.apache.soap.SOAPException; импортиране на org.apache.soap.encoding.SOAPMappingRegistry; импортиране на org.apache.soap.encoding.soapenc.BeanSerializer;импортиране на org.apache.soap.rpc.Call; импортиране на org.apache.soap.rpc.Parameter; импортиране на org.apache.soap.rpc.Response; импортиране на org.apache.soap.util.xml.QName; публичен клас CDAdder( public void add(URL url, String title, String artist, String label) хвърля SOAPException ( System.out.println("Добавяне на CD със заглавие "" + заглавие + "" изпълнител "" + изпълнител + "" студио " + етикет); CD cd = нов компактдиск (заглавие, изпълнител, етикет); // Създаване на обект за повикване Call Call call = new Call(); call.setSOAPMappingRegistry(регистър); call.setTargetObjectURI("urn:cd-каталог"); call.setMethodName("addCD"); call.setEncodingStyleURI(Константи.NS_URI_SOAP_ENC); // Задаване на параметри Vector params = new Vector(); params.addElement(нов параметър("cd", CD.class, cd, null)); call.setParams(params); // Обработка на отговора на Invoke call Response; отговор = call.invoke(url, ""); if (!response.generatedFault()) ( System.out.println("Добавянето на CD завърши успешно."); ) else ( Fault fault = response.getFault(); System.out.println(Грешка: " + fault.getFaultString ()); public static void main(String args) ( if (args.length != 4) ( System.out.println("Template: java javaxml2.CDAdder " + "\"[CD Title]\" \"[Име на изпълнител]\ " \"[Studio CD]\""); try ( // URL на SOAP сървъра, към който се осъществява връзката URL url = нов URL(args); // Получаване на стойности за нов CD String title = args; String artist = args; Етикет на низ = args; // Добавяне на CD CDAdder adder = new CDAdder(); adder.add(url, заглавие, изпълнител, етикет); ) catch (Изключение e) ( e.printStackTrace(); ) ) )

Единствената наистина интересна промяна е в картографирането на класове CD:

// Карта на този тип, така че да може да се използва със SOAP SOAPMappingRegistry регистър = нов SOAPMappingRegistry(); BeanSerializer сериализатор = нов BeanSerializer(); registry.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("urn:cd-catalog-demo", "cd"), CD.class, сериализатор, сериализатор);

Ето как даден потребителски параметър може да бъде кодиран и предаден по мрежата. Вече ви казах как класът BeanSerializerможе да се използва за обработка на параметри във формат JavaBean, като например клас CD. Използвах дескриптор на разположение, за да ги посоча на сървъра, въпреки че сега трябва да кажа на клиента да използва този сериализатор и десериализатор. Тази функция се изпълнява от класа SOAPMappingRegistry. Метод mapTypes()взема шифрования низ (отново, по-добре е да използвате константа за това NS_URI_SOAP_ENC), и информация за типа на параметъра, за който трябва да се използва специална сериализация. Първо се посочва QName. Ето защо странното пространство от имена е използвано в дескриптора на хостинга. Трябва да предоставите същия URN тук, както и локалното име на елемента (за този пример „CD“), след това Java обекта Класклас, който ще бъде сериализиран ( CD.клас) и накрая екземпляр на класа за сериализация и десериализация. За този пример и двата случая ще включват екземпляр BeanSerializer. След като всички тези настройки бъдат въведени в регистъра, уведомете обекта Обадете сеизползвайки метода setSOAPMapping-Registry().

Можете да стартирате този клас, както е показано по-рано, като добавите компактдиска и всичко трябва да работи както се очаква:

C:\javaxml2\build>java javaxml2.CDAdder http://localhost:8080/soap/servlet/rpcrouter "Tony Rice" "Manzanita" "Sugar Hill"Добавяне на компактдиск, озаглавен "Тони Райс" от "Manzanita" на Sugar Hill Успешно добавяне на компактдиск.

Напуснах модификацията на класа CDListerза теб. Всичко се произвежда по същия шаблон. За да тествате себе си, можете да се обърнете към примерните файлове за моята книга, които вече съдържат тези актуализирани класове.

Забележка: Можете да решите това, защото класът CDListerне взаимодейства директно с обекта CD(връща се от метод списък ()видът има значение Хеш таблица), тогава не е необходимо да правите никакви промени. Въпреки това върнатият клас Хеш таблицасъдържа екземпляри на обекти CD. Ако SOAP не знае как да ги десериализира, клиентът ще изведе грешка. В този случай, за да разрешите проблема, трябва да посочите в обекта Обадете секопие SOAPMappingRegistry.

Ефективно обработване на грешки

Сега, след като видяхте потребителски обекти и направихте RPC извиквания и други подобни, позволете ми да говоря за една по-малко вълнуваща тема: обработка на грешки. При всяка мрежова транзакция могат да възникнат много повреди. Услугата не стартира, има грешка в сървъра, обект не може да бъде намерен, липсват класове и много други проблеми. Досега просто използвах метода fault.getString()за генериране на съобщения за грешка. Но този метод може да не винаги е полезен. За да го видите в действие, разкоментирайте конструктора CDCatalog:

публичен CDCatalog() ( //каталог = нова хеш-таблица(); // Създаване на директория addCD(new CD("Nickel Creek", "Nickel Creek", "Sugar Hill")); addCD(нов CD("Let it Fall", "Sean Watkins", "Sugar Hill")); addCD(нов CD("Aerial Boundaries", "Michael Hedges", "Windham Hill")); addCD(нов CD("Taproot", "Michael Hedges", "Windham Hill")); )

Прекомпилирайте го, рестартирайте сървлет машината и го хоствайте отново. Това ще доведе до изключение NullPointerExceptionкогато конструкторът на класа се опитва да добави CD към неинициализиран Хеш таблица. При стартиране на клиента ще се появи съобщение за грешка, но няма да е много информативно:

(gandalf)/javaxml2/build$ java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcrouter Вижте текущата директория на CD. Грешка: Не може да се разреши целеви обект: нула

Това изобщо не е информацията, която може да помогне при идентифицирането и коригирането на грешка. Въпреки това рамката се справя добре с обработката на грешки. Помниш ли DOMFaultListener, която сте посочили като стойност на елемента faultListener? Дойде моментът той да влезе в играта. Обектът се връща в случай на грешка Грешкасъдържа DOM (документен обектен модел) org.w3c.dom.Elementс подробна информация за грешката. Първо добавете израз за импортиране към вашия изходен код java.util.Итератор:

импортиране на java.net.URL; импортиране на java.util.Enumeration; импортиране на java.util.Hashtable; импортиране на java.util.Iterator;импортиране на java.util.Vector; импортиране на org.apache.soap.Constants; импортиране на org.apache.soap.Fault; импортиране на org.apache.soap.SOAPException; импортиране на org.apache.soap.encoding.SOAPMappingRegistry; импортиране на org.apache.soap.encoding.soapenc.BeanSerializer; импортиране на org.apache.soap.rpc.Call; импортиране на org.apache.soap.rpc.Parameter; импортиране на org.apache.soap.rpc.Response; импортиране на org.apache.soap.util.xml.QName;

Сега нека направим промени за обработка на грешки в метода list():

if (!response.generatedFault()) ( Параметър returnValue = response.getReturnValue(); Hashtable catalog = (Hashtable)returnValue.getValue(); Изброяване e = catalog.keys(); while (e.hasMoreElements()) ( String title = (String)e.nextElement(); CD cd = (CD)catalog.get(title); System.out.println(" "" + cd.getTitle() + "" artist " + cd.getArtist() + " studios " + cd.getLabel()); else ( Fault fault = response.getFault(); System.out.println("Грешка: " + fault.getFaultString()); Векторни записи = 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());

Използване на метод getDetailEntries()получавате достъп до услугата SOAP и сървъра, поддържащ необработените данни с информация за проблема. Кодът ги обработва повторно (обикновено има само един елемент, но изисква внимателно внимание) и прихваща DOM елемент, съдържащи се във всеки запис. По същество ето XML, с който работите:

SOAP-ENV:Server.BadTargetObjectURI Не може да се разреши target: null Това е, което искаме!

С други думи, обектът Fault ви дава достъп до частта от SOAP обвивката, която съдържа грешки. В допълнение, Apache SOAP предоставя проследяване на стека на Java, когато възникнат грешки, предоставяйки подробната информация, необходима за коригирането им. Прихващане на елемент stackTraceи отпечатване на стойността на възела Текстот този елемент вашият клиент може да отпечата трасирането на стека на сървъра. Чрез компилиране на тези промени и рестартиране на клиента ще получите следния резултат:

C:\javaxml2\build>java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcr outer Вижте текущата директория на CD. Грешка: Не може да се разреши target: null java.lang.NullPointerException в javaxml2.CDCatalog.addCD(CDCatalog.java:24) в javaxml2.CDCatalog. (CDCatalog.java:14) в java.lang.Class.newInstance0(Native Method) в java.lang.Class.newInstance(Class.java:237)

Не е много по-добре, но поне можете да видите малко информация, че е възникнало изключение NullPointerExceptionи дори да разберете номерата на редовете в сървърните класове, в които е възникнал този проблем. Резултатът от тези последни промени ви даде ясна картина на проблема с обработката на грешки. Сега трябва да проверите вашите сървърни класове за грешки. Да, почти забравих, преди това не забравяйте да промените обратно класа си CDCatalogза да се отървете от грешките, които умишлено въведохме за яснота!

  1. Говори се много за изпълнение на SOAP през други протоколи като SMTP (или дори Jabber). Стандартът SOAP в момента не предоставя това, но подобни възможности може да бъдат добавени в бъдеще. Затова не се изненадвайте, ако срещнете активни дискусии по тази тема.
  • Урок

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

Надявам се, че след като прочетете темата, ще можете да:

  • напишете своя собствена сървърна реализация на уеб приложение;
  • напишете своя собствена клиентска реализация на уеб приложение;
  • напишете собствено описание на уеб услуга (WSDL);
  • изпрати клиентските масиви от същия тип данни към сървъра.
Както може би се досещате, цялата магия ще бъде направена с помощта на PHP и вградените класове SoapClient и SoapServer. Нашият заек ще бъде услуга за изпращане на SMS съобщения.

1 Постановка на проблем

1.1 Граници

В началото предлагам да се занимаем с резултата, който ще постигнем в края на темата. Както беше обявено по-горе, ще напишем услуга за изпращане на SMS съобщения и по-точно ще получаваме съобщения от различни източници чрез SOAP протокола. След което ще разгледаме под каква форма идват на сървъра. Процесът на поставяне на съобщения в опашка за по-нататъшно изпращане до доставчика, за съжаление, е извън обхвата на тази публикация по много причини.

1.2 Какви данни ще променим?

Страхотно, взехме решение за границите! Следващата стъпка, която трябва да се направи, е да решим какви данни ще обменяме между сървъра и клиента. По тази тема предлагам да не се разделяте твърде дълго и веднага да си отговорите на основните въпроси:
  • Какви минимални данни трябва да бъдат изпратени до сървъра, за да се изпрати SMS съобщение до абонат?
  • Какви минимални данни трябва да бъдат изпратени от сървъра, за да задоволят нуждите на клиента?
Нещо ми подсказва, че за това трябва да изпратите следното:
  • номер на мобилен телефон и
  • текст на SMS съобщението.
По принцип тези две характеристики са достатъчни за изпращане, но веднага си представям случая на SMS с поздравления за рожден ден, който ви идва в 3 часа сутринта или 4! В този момент ще бъда много благодарен на всички, че не ме забравят! Следователно ние също ще изпратим до сървъра и
  • датата на изпращане на SMS съобщението.
Следващото нещо, което бих искал да изпратя на сървъра е:
  • Тип съобщение.
Този параметър не е задължителен, но може да ни бъде много полезен, ако трябва бързо да кажем на шефа колко от нашите клиенти сме „зарадвали“ с нашите новини, както и да изготвим красива статистика по този въпрос.

И все пак, забравих нещо! Ако разгледаме малко повече, струва си да се отбележи, че клиентът може да изпрати едно SMS съобщение или няколко от тях на сървъра наведнъж. С други думи, един пакет данни може да съдържа от едно до безкрайност съобщения.

В резултат на това получаваме, че за изпращане на SMS съобщение се нуждаем от следните данни:

  • Номер на мобилен телефон,
  • текст на SMS съобщение,
  • време на изпращане на SMS съобщението до абоната,
  • тип съобщение.

Отговорихме на първия въпрос, сега трябва да отговорим на втория въпрос. И може би ще си позволя да се забъркам малко. Следователно от сървъра ще изпращаме само булеви данни, чието значение има следното значение:

  • ВЯРНО – пакетът е достигнал успешно сървъра, преминал е удостоверяване и е поставен на опашка за изпращане до доставчика на SMS
  • FALSE – във всички останали случаи

Това завършва описанието на постановката на проблема! И накрая, нека преминем към забавната част - нека разберем какъв странен звяр е този САПУН!

2 Какво е SOAP?

Като цяло, първоначално не планирах да пиша нищо за това какво е SOAP и исках да се огранича до връзки към уебсайта w3.org с необходимите спецификации, както и връзки към Wikipedia. Но в самия край реших да напиша кратка бележка за този протокол.

И ще започна моята история с факта, че този протокол за обмен на данни принадлежи към подгрупа от протоколи, базирани на така наречената RPC (Remote Procedure Call) парадигма, чийто антипод е REST (Representational State Transfer). Можете да прочетете повече за това в Wikipedia; връзките към статиите са в самия край на темата. От тези статии трябва да разберем следното: „RPC подходът позволява използването на малък брой мрежови ресурси с голям брой методи и сложен протокол. С подхода REST броят на методите и сложността на протокола са строго ограничени, което означава, че броят на отделните ресурси може да бъде голям. Тоест по отношение на нас това означава, че в случай на RPC подход на сайта винаги ще има един вход (връзка) към услугата и каква процедура да се извика за обработка на входящи данни, които прехвърляме заедно с данните, докато с подхода REST в нашия Сайтът има много входове (линкове), всеки от които приема и обработва само определени данни. Ако някой четящ знае как да обясни разликата в тези подходи още по-просто, не забравяйте да напишете в коментарите!

Следващото нещо, което трябва да знаем за SOAP е, че този протокол използва същия XML като транспорт, което от една страна е много добро, т.к. Нашият арсенал незабавно включва пълната мощ на набор от технологии, базирани на този език за маркиране, а именно XML-Schema - език за описание на структурата на XML документ (благодаря на Wikipedia!), който позволява автоматично валидиране на данните, получени от сървъра от клиенти.

И така, сега знаем, че SOAP е протокол, използван за внедряване на извиквания на отдалечени процедури и използва XML като транспорт! Ако прочетете статията в Wikipedia, можете също да научите от там, че може да се използва върху всеки протокол на ниво приложение, а не само в комбинация с HTTP (за съжаление, в тази тема ще разгледаме само SOAP през HTTP). И знаете ли какво ми харесва най-много във всичко това? Ако няма предположения, тогава ще дам намек - SOAP!... Все още няма предположения?... Сигурни ли сте, че сте прочели статията в Уикипедия?... Като цяло, няма да ви измъчвам повече. Затова ще премина направо към отговора: „SOAP (от английски Simple Object Access Protocol - прост протоколдостъп до обекти; до спецификация 1.2)". Най-забележителното в този ред е в курсив! Не знам какви изводи сте направили от всичко това, но виждам следното - тъй като този протокол по никакъв начин не може да се нарече "прост" (и очевидно дори w3 е съгласен с това), тогава от версия 1.2 той спря да се декриптира по някакъв начин ! И стана известен като SOAP, просто SOAP, точка.

Е, добре, моля да ме извините, малко се отклоних. Както писах по-рано, XML се използва като транспорт, а пакетите, които пътуват между клиента и сървъра, се наричат ​​SOAP пликове. Ако разгледате общата структура на плика, тя ще ви се стори много позната, защото... наподобява структурата на HTML страница. Има основен раздел - Плик, който включва раздели ЗаглавкаИ Тяло, или Грешка. IN Тялоданните се предават и са задължителен раздел от плика, докато Заглавкане е задължително. IN Заглавкаразрешение или други данни, които не са пряко свързани с входните данни на процедурите на уеб услугата, могат да бъдат предадени. относно Грешканяма какво специално да се каже, освен че идва на клиента от сървъра в случай на грешки.

Това е мястото, където моята рецензионна история за SOAP протокола свършва (ще разгледаме самите пликове и тяхната структура по-подробно, когато нашият клиент и сървър най-накрая се научат да ги изпълняват един на друг) и започва нова - за SOAP компаньона, наречен WSDL(Език за описание на уеб услуги). Да, да, това е нещото, което плаши повечето от нас дори да се опитаме да внедрим нашия API на този протокол. В резултат на това обикновено преоткриваме нашето колело с JSON като транспорт. И така, какво е WSDL? WSDL е език за описание на уеб услуги и достъп до тях, базиран на XML езика (c) Wikipedia. Ако тази дефиниция не ви изяснява целия сакрален смисъл на тази технология, то аз ще се опитам да я опиша със свои думи!

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

  • Какви пространства от имена са използвани?
  • Какви схеми на данни са използвани?
  • Какви видове съобщения очаква уеб услугата от клиентите?
  • Кои данни принадлежат към кои процедури на уеб услуга,
  • Какви процедури съдържа уеб услугата?
  • Как трябва клиентът да извика процедурите на уеб услугата,
  • На кой адрес трябва да се изпращат клиентските обаждания?
Както можете да видите, този файл е цялата уеб услуга. Посочвайки адреса на WSDL файла в клиента, ние ще знаем всичко за всяка уеб услуга! В резултат на това не е нужно да знаем абсолютно нищо за това къде се намира самата уеб услуга. Всичко, което трябва да знаете, е местоположението на неговия WSDL файл! Скоро ще разберем, че SOAP не е толкова страшен, колкото го представят руските поговорки.

3 Въведение в XML-схемата

Сега знаем много за това какво е SOAP, какво има вътре в него и имаме преглед на стека от технологии, който го заобикаля. Тъй като, на първо място, SOAP е метод за взаимодействие между клиент и сървър и езикът за маркиране на XML се използва като транспорт за него, в този раздел ще разберем малко за това как се извършва автоматичното валидиране на данни с помощта на XML схеми.

Основната задача на диаграмата е да опише структурата на данните, които ще обработваме. Всички данни в XML схемите са разделени на просто(скалар) и комплекс(структури) видове. Простите типове включват следните видове:

  • линия,
  • номер,
  • булева стойност,
  • дата на.
Нещо много просто, което няма разширения вътре. Техен антипод са сложните комплексни типове. Най-простият пример за сложен тип, който идва на ум на всеки, са обектите. Например книга. Книгата се състои от свойства: автор, Име, цена, ISBN номери т.н. А тези свойства от своя страна могат да бъдат или прости типове, или сложни. И задачата на XML схемата е да опише това.

Предлагам да не отиваме далеч и да напишем XML схема за нашето SMS съобщение! По-долу е xml описанието на SMS съобщението:

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


Този запис гласи следното: Имаме променлива " съобщение" Тип " Съобщение" и има сложен тип, наречен " Съобщение", който се състои от последователен набор от елементи " телефон" Тип низ, « текст" Тип низ, « дата" Тип Време за среща, « Тип" Тип десетичен знак. Тези типове са прости и вече са дефинирани в описанието на схемата. Честито! Току-що написахме първата си XML схема!

Мисля, че значението на елементите " елемент" И " комплексен тип„Всичко ви стана повече или по-малко ясно, така че няма да се фокусираме повече върху тях и нека преминем направо към елемента на композитора“ последователност" Когато използваме елемента composer " последователност„Информираме ви, че включените в него елементи винаги трябва да са разположени в последователността, посочена в схемата, и всички те са задължителни. Но не се отчайвайте! В XML схемите има още два композиторски елемента: " избор" И " всичко" Композитор " избор" обявява, че трябва да има един от елементите, изброени в него, и композиторът " всичко» – произволна комбинация от изброените елементи.

Както си спомняте, в първия раздел на темата се съгласихме, че от един до безкрайност SMS съобщенията могат да се предават в пакет. Затова предлагам да разберем как такива данни се декларират в XML схемата. Общата структура на пакета може да изглежда така:

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


Първият блок съдържа познатата декларация от сложен тип „ Съобщение" Ако сте забелязали, тогава във всеки прост тип, включен в " Съобщение", добавени са нови поясняващи атрибути " minOccurs" И " maxOccurs" Както можете да се досетите от името, първият ( minOccurs) показва, че тази последователност трябва да съдържа поне един елемент от тип „ телефон», « текст», « дата" И " Тип", докато следващият ( maxOccurs) атрибут ни декларира, че има най-много един такъв елемент в нашата последователност. В резултат на това, когато пишем свои собствени схеми за всякакви данни, ни се дава най-широк избор как да ги конфигурираме!

Вторият блок на диаграмата декларира елемента " messageList" Тип " Списък със съобщения" Ясно е, че " Списък със съобщения" е сложен тип, който съдържа поне един елемент " съобщение“, но максималният брой такива елементи не е ограничен!

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 основни блока. Първият блок е дефиницията на уеб услуга или, с други думи, входната точка.


Тук пише, че имаме услуга, наречена - “ SmsService" По принцип всички имена в WSDL файла могат да се променят от вас на каквито искате, т.к те не играят абсолютно никаква роля.

След това съобщаваме, че в нашата уеб услуга " SmsService" има входна точка ("порт"), наречена " SmsServicePort" Към тази входна точка ще се изпращат всички заявки от клиенти към сървъра. И посочете в елемента „ адрес» връзка към файла на манипулатора, който ще приема заявки.

След като сме дефинирали уеб услугата и сме посочили входната точка за нея, трябва да обвържем поддържаните процедури към нея:


За да направите това, той изброява кои операции и под каква форма ще бъдат извикани. Тези. за порт" SmsServicePort" обвързване е дефинирано под името " SmsServiceBinding", който има тип повикване " rpc"и HTTP се използва като протокол за трансфер. По този начин ние посочихме тук, че ще направим RPC повикване през HTTP. След това описваме кои процедури ( операция) се поддържат в уеб услугата. Ще подкрепим само една процедура – ​​“ изпрати SMS" Чрез тази процедура нашите прекрасни съобщения ще бъдат изпратени до сървъра! След деклариране на процедурата е необходимо да се посочи под каква форма ще се предават данните. В този случай е посочено, че ще се използват стандартни 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 сървъра кой клас трябва да бъде изтеглен, за да обработи плика, получен от клиента, и да върне плика с отговора. Както може би се досещате, в този клас ще бъде описан единственият ни метод изпрати SMS. На третия ред стартираме сървъра! Това е всичко, нашият сървър е готов! С което ни поздравявам всички!

Сега трябва да създадем 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 клиент на път

На първо място, трябва да създадем файл, в който ще запишем клиента. Както обикновено, ще го създадем в корена на хоста и ще го наречем " client.php“, а вътре ще напишем следното:

messageList = нов MessageList(); $req->messageList->message = ново съобщение(); $req->messageList->message->phone = "79871234567"; $req->messageList->message->text = "Тест съобщение 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->message->type = 15; $client = нов SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($client->sendSms($req));
Нека опишем нашите обекти. Когато написахме WSDL, той описа три обекта за плика, входящ към сървъра: Заявка, Списък със съобщенияИ Съобщение. Съответно класове Заявка, Списък със съобщенияИ Съобщениеса отражения на тези обекти в нашия PHP скрипт.

След като дефинираме обектите, трябва да създадем обект ( $req), които ще изпратим на сървъра. След което идват двете най-съкровени за нас реплики! Нашият SOAP клиент! Вярвате или не, това е достатъчно сървърът ни да започне да получава съобщения от клиента, както и сървърът ни да ги приеме и обработи успешно! В първия от тях създаваме екземпляр на класа SoapClient и предаваме адреса на местоположението на WSDL файла на неговия конструктор, като в параметрите изрично указваме, че ще работим по SOAP протокол версия 1.2. На следващия ред извикваме метода изпрати SMSобект $ клиенти веднага да покаже резултата в браузъра.
Нека го стартираме и да видим какво имаме най-накрая!

Следният обект ми беше върнат от сървъра:

Object(stdClass) public "status" => boolean true
И това е страхотно, защото... Сега знаем със сигурност, че нашият сървър работи и не само работи, но и може да върне някои стойности на клиента!

Сега нека да разгледаме дневника, който благоразумно съхраняваме от страна на сървъра! В първата му част виждаме необработените данни, пристигнали на сървъра:

79871234567 Тестово съобщение 1 2013-07-21T15:00:00.26 15
Това е пликът. Сега знаете как изглежда! Но е малко вероятно да се интересуваме да го разглеждаме през цялото време, така че нека десериализираме обекта от лог файла и да видим дали всичко е наред:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => низ "79871234567" (length=11) public "text" => низ "Тест съобщение 1 " (length=37) public "date" => низ "2013-07-21T15:00:00.26" (length=22) public "type" => низ "15" (length=2)
Както можете да видите, обектът беше десериализиран правилно, за което искам да поздравя всички ни! Очаква ни още нещо интересно! А именно, ние ще изпратим на клиента до сървъра не само едно SMS съобщение, а цял пакет (по-точно три)!

7 Изпращане на сложни обекти

Нека помислим как можем да прехвърлим цял куп съобщения към сървъра в един пакет? Вероятно най-лесният начин би бил да организирате масив вътре в елемента messageList! Да го направим:

// създаване на обект за изпращане на сървъра $req = new Request(); $req->messageList = new MessageList(); $msg1 = ново съобщение(); $msg1->телефон = "79871234567"; $msg1->text = "Тест съобщение 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->тип = 15; $msg2 = ново съобщение(); $msg2->телефон = "79871234567"; $msg2->text = "Тест съобщение 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->тип = 16; $msg3 = ново съобщение(); $msg3->телефон = "79871234567"; $msg3->text = "Тест съобщение 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->тип = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $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
Какви глупости ще кажете? И ще бъдете прави в известен смисъл, защото... Веднага след като научихме, че даден обект напусна клиента, той дойде на нашия сървър в абсолютно същата форма под формата на плик. Вярно е, че SMS съобщенията не бяха сериализирани в XML по начина, по който ни трябваше - те трябваше да бъдат обвити в елементи съобщение, Не в Структура. Сега нека видим под каква форма такъв обект идва в метода изпрати SMS:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "Struct" => масив (size=3) 0 => object(stdClass) public "phone" => низ "79871234567" (length=11) public "text" => string "Test message 1" (length=37) public "date" => string "2013-07-21T15:00:00.26" (length=22) public " type" => низ "15" (length=2) 1 => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "Test message 2" (length= 37) public "date" => низ "2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone " => низ "79871234567" (length=11) public "text" => string "Test message 3" (length=37) public "date" => string "2014-08-22T16:01:10" (length= 19) публичен "тип" => низ "17" (дължина=2)
Какво ни дава това знание? Само, че пътят, който избрахме, не е правилен и не получихме отговор на въпроса - "Как да получим правилната структура на данните на сървъра?" Но предлагам да не се отчайваме и да се опитаме да преобразуваме нашия масив в типа предмет:

$req->messageList->message = (обект)$req->messageList->message;
В този случай ще получим още един плик:

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
Стигнах до метода изпрати SMSобектът има следната структура:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "BOGUS" => масив (size=3) 0 => object(stdClass) public "phone" => низ "79871234567" (length=11) public "text" => string "Test message 1" (length=37) public "date" => string "2013-07-21T15:00:00.26" (length=22) public " type" => низ "15" (length=2) 1 => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "Test message 2" (length= 37) public "date" => низ "2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone " => низ "79871234567" (length=11) public "text" => string "Test message 3" (length=37) public "date" => string "2014-08-22T16:01:10" (length= 19) публичен "тип" => низ "17" (дължина=2)
Що се отнася до мен, „сумата не се променя от смяна на местата на членовете“ (c). Какво ФАЛШИВНИ, Какво Структура– още не сме постигнали целта си! И за да го постигнем, трябва да се уверим, че вместо тези неразбираеми имена се показва нашето родно съобщение. Но авторът все още не знае как да постигне това. Следователно единственото нещо, което можем да направим, е да се отървем от допълнителния контейнер. С други думи, сега ще се уверим, че вместо съобщениестана ФАЛШИВНИ! За да направите това, променете обекта, както следва:

// създаване на обект за изпращане на сървъра $req = new Request(); $msg1 = ново съобщение(); $msg1->телефон = "79871234567"; $msg1->text = "Тест съобщение 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->тип = 15; $msg2 = ново съобщение(); $msg2->телефон = "79871234567"; $msg2->text = "Тест съобщение 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->тип = 16; $msg3 = ново съобщение(); $msg3->телефон = "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
Да, чудо не се случи! ФАЛШИВНИ– няма да спечелим! Дойде в изпрати SMSобектът в този случай ще изглежда така:

Object(stdClass) public "messageList" => object(stdClass) public "BOGUS" => array (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (length=11) public " текст" => низ "Тестово съобщение 1" (дължина=37) публичен "дата" => низ "2013-07-21T15:00:00.26" (дължина=22) публичен "тип" => низ "15" (дължина =2) 1 => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "Test message 2" (length=37) public "date" => string " 2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone" => string "79871234567" (length= 11) public "text" => string "Test message 3" (length=37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string " 17" (дължина=2)
Както се казва – „Почти“! На тази (леко тъжна) бележка, предлагам бавно да приключим нещата и да направим някои заключения за себе си.

8 Заключение

Най-накрая стигнахме до тук! Нека да разберем какво можете да направите сега:
  • можете да напишете WSDL файла, необходим за вашата уеб услуга;
  • можете лесно да напишете свой собствен клиент, който може да комуникира със сървъра чрез SOAP;
  • можете да напишете свой собствен сървър, който комуникира с външния свят чрез SOAP;
  • можете да изпращате масиви от същия тип обекти към сървъра от вашия клиент (с някои ограничения).
Направихме и някои открития по време на нашето малко проучване:
  • собственият клас SoapClient не сериализира правилно структури от данни от същия тип в XML;
  • когато сериализира масив в XML, той създава допълнителен елемент, наречен Структура;
  • когато сериализира обект в XML, той създава допълнителен елемент, наречен ФАЛШИВНИ;
  • ФАЛШИВНИпо-малко зло от Структурапоради факта, че пликът е по-компактен (не се добавят допълнителни пространства от имена към XML хедъра на плика);
  • За съжаление, класът SoapServer не валидира автоматично данните от плика с нашата XML схема (може би други сървъри също не правят това).

Няма да се спирам на въпроса какво представлява уеб услугии защо са необходими. В интернет има много статии по тази тема. Просто ще се опитам накратко да покажа колко лесно е да създадете клиент за всяка уеб услуга в PHP.

Настройки

За използване САПУНв php трябва да свържете SOAP модула (включен в дистрибуцията на php5). Под Windows това се прави просто - трябва да добавите (именно добавите, тъй като този ред не е просто коментиран там, той изобщо липсва) в php.ini:
разширение=php_soap.dll

Не забравяйте да рестартирате сървъра, ако имате инсталиран php като модул.


Създаване на SOAP клиент от WSDL документ

Създаването на SOAP клиент обикновено става от WSDL документ, който е XML документ в специфичен формат, който напълно описва определена уеб услуга. За подробности относно WSDL ви препращам към уебсайта на консорциума на W3C - http://www.w3.org/TR/2005/WD-wsdl20-soap11-binding-20050510/.

Основното нещо, което трябва да знаете, за да създадете клиент за уеб услуга, е да знаете URL адреса на нейния WSDL документ.
Например, нека вземем уеб услугата „Валутен обменен курс“ от xmethods.com. Адресът на тази уеб услуга, която ви позволява да получавате обменни курсове онлайн, е http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl.

Вторият важен момент е, че от описанието на уеб услугата е необходимо да се получи информация за това какви методи предоставя тази услуга и какви параметри трябва да й предадем като входни стойности (много подобно на извикването на обикновена PHP функция или клас метод). Обикновено тази информация се съдържа в описанието на услугата на нейния уебсайт. Нашата уеб услуга за получаване на обменни курсове предоставя метода getRate(), към който кодовете на валутите се подават като аргументи.

И последно, важно е да знаете какво да очаквате като отговор: колко стойности, какъв тип и т.н. Това може да се получи и от описанието.
И в резултат на това кодът се оказва много прост и компактен, почти елементарен:

// Използване на уеб услугата
// „Обменен курс“ от xmethods.com

// Създаване на SOAP клиент от WSDL документ
$клиент = нов SoapClient("http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl");

// Изпращане на SOAP заявка и получаване на резултата
$result = $client->getRate("us", "russia");

Echo ‘Текущ обменен курс на долара: ’, $резултат, ‘рубли’;
?>

Както можете да видите от кода, трябва да предадете URL адреса на WSDL документа на конструктора на клас SoapClient и да получите обект, който да работи с желаната уеб услуга. След това се извиква метод на този обект, чието име е същото като името на самия метод на уеб услугата. Този метод връща резултата, който искаме.

И така, този прост пример илюстрира принципа за изграждане на SOAP клиент за уеб услуги в PHP. Въпреки това, в реално приложение все още има много неща, за които трябва да се погрижите, по-специално фактът, че когато се извика уеб услугата, тя може да бъде временно недостъпна или да върне грешка. Ясно предлага използването на блок опитвам/хващам/хвърлям :)

Тук, в LeaseWeb, ние работим много със SOAP уеб услуги, за да интегрираме нашите вътрешни приложения едно с друго. Особено по време на разработката и тестването на нашите приложения, тъй като се нуждаем от способността да практикуваме със SOAP API.

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

Това ще изтегли phar файла в текущата работна директория и ще го направи изпълним, така че можете да започнете да го използвате веднага, като извикате:

$ ./soap_client

За да инсталирате най-новата основна версия, можете да получите изходния код директно от GitHub, да пакетирате свой собствен .phar файл и да го инсталирате - с помощта на GNU Make.
За да можете да създадете .phar файла, трябва да имате инсталиран композитор. За да прочетете повече за composer, вижте тяхната отлична документация.

# Инсталиране на php soap клиент $ git clone https://github.com/LeaseWeb/php-soap-client.git $ cd php-soap-client $ composer.phar install $ make $ sudo make install

Ако получавате изключение Неуспешно компилиране на phar, докато работите, трябва да зададете phar.readonly = Off във вашия php.ini. На машина за разработка това е добре, но имайте предвид рисковете за сигурността, когато настройвате phar.readonly на Off.

Горната команда make install ще инсталира приложението soap_client в /usr/local/bin и ще го направи изпълнимо, за да можете лесно да го извикате по следния начин:

$ soap_client php-soap-client версия 2.1.3 Употреба: команда Опции: ... Налични команди: call Обадете се на отдалечената услуга с посочения `method` и изведете отговора на stdout. help Показва помощ за списък с команди Списъци с команди list-methods Вземете списък с налични методи за извикване на дистанционното. заявка Генериране на SOAP заявка във формат xml за дадения метод и извеждане към stdout. wsdl Вземете WSDL на сапунена услуга.

От този момент нататък приемаме, че сте инсталирали soap_client.phar на вашата система в /usr/local/bin/soap_client и че директорията /urs/local/bin е във вашия $PATH.

Да кажем, че бихме искали да видим какви методи са налични в отдалечената услуга http://www.webservicex.net/ConvertTemperature.asmx. Можем да издадем следната команда:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" списък-методи

Което ще изведе следното:

ConvertTemp

Ако изпълните горната команда с опцията -vvv, ще получите по-подробен изход.
В този случай единственият наличен метод е ConvertTemp. Нека видим как изглежда SOAP XML заявка за този метод:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" заявка ConvertTemp 0

Ако искате да направите SOAP заявка към метода ConvertTemp на отдалечената услуга, използвайте командата call sub:

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

Забележете опцията --editor след командата call sub. Ако използвате флага --editor, soap_client ще отвори редактора, посочен във вашата променлива на обкръжението $EDITOR, така че да можете да промените XML заявката, преди да я изпратите.

Ако подадете една и съща заявка няколко пъти, можете да запишете заявка за сапун като локален XML файл и да я предадете на /dev/stdin на командата за извикване soap_client:

# Вземете xml заявката и я запазете локално $ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" request ConvertTemp > my_sample_request.xml # Сега редактирайте my_sample_request.xml # Сега можете да извикате Метод ConvertTemp с тази предварително подготвена заявка $ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" call ConvertTemp< my_sample_request.xml

Тъй като ще повтаряте команди soap_client често за кратко време, докато изследвате отдалечена уеб услуга, можете да си спестите малко време, като зададете променлива на средата SOAPCLIENT_ENDPOINT, която съдържа URL адреса към WSDL. Когато тази променлива на средата е зададена, можете да пропуснете опцията на командния ред --endpoint. Нека направим това сега и извикаме метода ConvertTemp:

$ export SOAPCLIENT_ENDPOINT="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" $ soap_client извикване ConvertTemp< my_sample_request.xml

Исках да знам колко е 107,6 градуса по Фаренхайт по Целзий, така че моят my_sample_request.xml съдържа:

$ cat my_sample_request.xml 107.6 градус по Фаренхайт градус по Целзии

$ soap_client извикване ConvertTemp< my_sample_request.xml stdClass Object ( => 42)

Отговорът е 42.

Ако предпочитате да виждате отговорите в XML формат, можете да използвате опцията на командния ред --xml:

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

Този урок трябва да ви даде достатъчно информация, за да започнете да изследвате, тествате и/или разработвате SOAP API.
В бъдеща публикация в блога ще продължа темата за php soap клиента. В момента работим върху опаковането на .phar архива за уеб.

Лирическа част.

Представете си, че сте внедрили или внедрявате определена система, която трябва да бъде достъпна отвън. Тези. има определен сървър, с който трябва да комуникирате. Например уеб сървър.

Този сървър може да извършва много действия, да работи с базата данни, да изпълнява някои заявки на трети страни към други сървъри, да прави някои изчисления и т.н. живее и евентуално се развива според сценария, който му е известен (т.е. според сценария на разработчиците). За човек не е интересно да комуникира с такъв сървър, защото може да не може/иска да предоставя красиви страници със снимки и друго удобно за потребителя съдържание. Той е написан и работи, за да работи и да предоставя данни, когато му бъдат поискани, без да се притеснявате, че е четим от хора, клиентът ще се справи сам с него.

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

Е, една от възможностите за комуникация с такива сървъри е SOAP. SOAP xml протокол за обмен на съобщения.

Практическа част.

Уеб услуга (това е името на това, което сървърът предоставя и което клиентите използват) прави възможно комуникацията със сървъра с ясно структурирани съобщения. Факт е, че уеб услугата не приема никакви данни. Уеб услугата ще отговори с грешка на всяко съобщение, което не отговаря на правилата. Грешката, между другото, също ще бъде в xml форма с ясна структура (което не е вярно за текста на съобщението).

WSDL (Език за описание на уеб услуги). Правилата, по които се съставят съобщенията за уеб услугата, също са описани с помощта на xml и също имат ясна структура. Тези. Ако дадена уеб услуга предоставя възможност за извикване на метод, тя трябва да позволи на клиентите да знаят какви параметри се използват за този метод. Ако уеб услугата очаква низ за Method1 като параметър и низът трябва да бъде наречен Param1, тогава тези правила ще бъдат посочени в описанието на уеб услугата.

Не само прости типове, но и обекти и колекции от обекти могат да бъдат предавани като параметри. Описанието на обекта се свежда до описание на всеки компонент на обекта. Ако обектът се състои от няколко полета, тогава се описва всяко поле, неговият тип, име (какви са възможните стойности). Полетата могат да бъдат и от сложен тип и така нататък, докато описанието на типовете завърши с прости - низ, булево, число, дата... Но някои специфични типове може да се окажат прости, важно е клиентите могат да разберат какви стойности могат да съдържат.

За клиентите е достатъчно да знаете URL адреса на уеб услугата; wsdl винаги ще бъде наблизо, от който можете да получите представа за методите и техните параметри, които тази уеб услуга предоставя.

Какви са предимствата на всички тези звънци и свирки:

  • В повечето системи описанието на методите и типовете става автоматично. Тези. програмистът на сървъра просто трябва да каже, че този метод може да бъде извикан чрез уеб услуга и wsdl описанието ще се генерира автоматично.
  • Описанието, което има ясна структура, се чете от всеки клиент на сапун. Тези. без значение каква е уеб услугата, клиентът ще разбере какви данни получава уеб услугата. Използвайки това описание, клиентът може да изгради собствена вътрешна структура от обектни класове, т.нар. обвързване" и. В резултат на това програмистът, използващ уеб услугата, трябва да напише нещо като (псевдокод):

    NewUser:=TSoapUser.Create("Vasya","Pupkin","admin"); soap.AddUser(NewUser);

  • Автоматично валидиране.

    • xml валидиране. xml трябва да е добре оформен. Невалиден xml - веднага грешка на клиента, нека се оправи.
    • валидиране на схема. xml трябва да има определена структура. xml не отговаря на схемата - веднага грешка на клиента, нека го оправи.
    • Проверката на данните се извършва от сървъра за сапун, така че типовете данни и ограниченията да съответстват на описанието.
  • Упълномощаването и удостоверяването могат да бъдат реализирани с помощта на отделен метод. нативно. или чрез http авторизация.
  • Уеб услугите могат да работят както чрез протокола soap, така и чрез http, тоест чрез заявки за получаване. Тоест, ако параметрите са прости данни (без структура), тогава можете просто да извикате обичайния get www.site.com/users.asmx/GetUser?Name=Vasia или post. Това обаче не е навсякъде и не винаги.
  • ... виж в Уикипедия

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

  • Неоправдано голям размер на съобщението. Е, тук самата природа на xml е такава, че форматът е излишен, колкото повече тагове, толкова повече безполезна информация. Освен това сапунът добавя своята излишност. За интранет системите проблемът с трафика е по-малко остър, отколкото за интернет, така че сапунът за локални мрежи е по-търсен, по-специално Sharepoint има сапунена уеб услуга, с която можете да комуникирате успешно (и с някои ограничения).
  • Автоматичната промяна на описанието на уеб услуга може да повреди всички клиенти. Е, така е за всяка система, ако не се поддържа обратна съвместимост със стари методи, всичко ще падне...
  • Не е минус, а недостатък. Всички извиквания на метод трябва да са атомарни. Например, когато работим с база данни, можем да започнем транзакция, да изпълним няколко заявки, след това да върнем назад или да извършим комит. Няма транзакции в сапун. Една молба, един отговор, разговорът приключи.
  • Справянето с описанието на това, което е от страната на сървъра (правилно ли е описано всичко?) и това, което е на клиента (какво ми беше описано тук?) може да бъде доста трудно. Имаше няколко пъти, когато трябваше да се занимавам с клиентската страна и да убеждавам сървърния програмист, че данните му са описани неправилно, но той изобщо не можеше да разбере нищо за това, защото автоматичното генериране и не трябва, това е въпрос на софтуер. И грешката, естествено, беше в кода на метода, програмистът просто не я видя.
  • Практиката показва, че разработчиците на уеб услуги са ужасно далеч от хората, които използват тези уеб услуги. В отговор на всяка заявка (валидна отвън) може да дойде неразбираема грешка „Грешка 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 Content-Length: length SOAPAction: "http://webservices.belavia.by/GetAirportsList" ru

отговорът ще дойде:

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 Cache-Control: частен, макс. -age=0 Тип съдържание: текст/xml; charset=utf-8 Дължина на съдържанието: 2940

PS Преди това беше отворена уеб услугата на Aeroflot, но след като 1C добави поддръжка на сапун към 8ku, куп 1C бета тестери успешно я инсталираха. Сега там нещо се промени (не знам адреса, можете да го потърсите, ако ви интересува).
ZZY Отказ от отговорност. Говореше на битово ниво. Можеш да риташ.

изгледи