Технологія SOAP

Лабораторна робота


Технологія SOAP



Мета
: отримання практичних навиків обміну даними між прикладенням C++ Builder і базою даних інформаційної системи в комп'ютерній мережі Internet з використанням технології SOAP
.


Завдання:


Створити оригінальну (!) розподілену інформаційну системуна основі технології SOAP
на прикладі системи з наступною архітектурою клієнт-серверної взаємодії:


· клієнтське прикладення де-небудь з Internet споживає Web-сервіс;


· Web-сервіс (через SOAP
) виставляє об'єктні методи;


· об'єктні методи звертаються до віддалених даних де завгодно на Web.


Технологія SOAP



Малюнок 1


Клієнт SOAP
використовує спеціальний UDDI-реєстр для локалізації Web-сервісу. В більшості випадків, замість керування WSDL безпосередньо, прикладення SOAP
буде сконструйовано так, щоб використовувати специфічний тип порту і стиль скріплення, і динамічно конфігуруватиме адресу сервісу, що викликається з метою узгодження з сервісом, знайденим за допомогою UDDI.


Клієнтське прикладення створює повідомлення SOAP
, яке є XML-документом, здатним здійснювати необхідні операції запиту / відповіді.


Клієнт посилає SOAP
повідомлення JSP
або ASP-сторінці
на Web-сервері, що слухає запити SOAP
.


Сервер SOAP
аналізує пакет SOAP
і викликає відповідний метод об'єкту в його області, передаваній в параметрах SOAP-документа.
Перед ухваленням повідомлення SOAP-сервером
вузли проміжної обробки можуть виконувати спеціальні функції, як вказано в заголовках SOAP
.


Запрошуваний об'єкт виконує позначену функцію і повертає дані SOAP-серверу
, який запаковує відповідь в конверт SOAP
. Потім сервер «кладе» конверт SOAP
в об'єкт відповіді (наприклад, сервлет або COM-об'єкт), який і посилається назад запитуючій машині.


Клієнт одержує об'єкт, «знімає» конверт SOAP
і посилає у відповідь документ програмі, що спочатку запитала його, завершуючи цикл запиту / відповіді.


Delphi
дозволяє створювати як сервери, так і клієнти Web Services
. Ми почнемо розгляд із створення сервера.


Створення сервера Web Services


Створення сервера Web Services
в Delphi
складається з наступних етапів:


1. Опис інтерфейсу сервера, тобто методів, які будуть доступні для виклику клієнту;


2. Реалізація методів сервера;


3. Створення проекту Delphi
і включення в нього результатів перших двох кроків.


У Delphi при створенні сервера Web Services
методи, доступні для виклику клієнту, описуються у вигляді invokable інтерфейсів
. Invokable інтерфейс
- це інтерфейс, для методів якого доступна RTTI
(інформація про типи на етапі виконання). Для того, щоб із звичайного інтерфейсу зробити invokable
досить вказати директиву компіляції {$M+}. Після цього всі нащадки і сам інтерфейс міститимуть RTTI. У ієрархії VCL вже є такий інтерфейс IInvokable
. Таким чином, при написанні сервера простіше всього успадкувати інтерфейс IInvokable
. Крім того, необхідно зареєструвати свій інтерфейс в invocation registry
. Реєстрація дозволяє серверу визначити клас, що реалізовує методи інтерфейсу, а клієнту одержати опис методів, підтримуваних сервером. Реєстрація здійснюється викликом методу InvRegistry.RegisterInterface у секції initialization
модуля.


Оскільки інтерфейс використовується не тільки сервером, але і клієнтом, то бажано визначити його в окремому модулі Delphi
.


Для прикладу ми розробимо сервер, який здійснюватиме перерахунок грошей з € у гривні і назад. У RAD Delphi
оберімо пункт меню File | New | Unit. У одержаному порожньому модулі визначимо інтерфейс сервера:


unit u_Intrf;


interface


type


IEncodeDecode = interface(IInvokable)


['{9298D805-A2FB-4860-994E-11CC5BD36025}']


// Конвертація Евро в Гривни


function EuroToUk(Value: Currency): Currency; stdcall;


// Конвертація Гривнею в Евро


function UkToEuro(Value: Currency): Currency;


stdcall;


end;


implementation


uses InvokeRegistry;


initialization


InvRegistry.RegisterInterface(TypeInfo(IEncodeDecode));


end.


Зверніть увагу, що рядок ['{9298D805-A2FB-4860-994E-11CC5BD36025}'] – це GUID інтерфейсу. Для коректної роботи прикладу необхідно згенерувати його, а не вводити уручну або копіювати з наведеного тексту. Генерація GUID в RAD Delphi
викликається натисненням Ctrl+Shift+G.


У разі використання у функціях інтерфейсу скалярних типів даних генерація SOAP-повідомлень
відбувається автоматично без додаткових зусиль з боку програміста. Якщо потрібно використовувати складні типи даних, такі як статичні масиви, набори і класи, то необхідно створити і зареєструвати клас-спадкоємець від TRemotableXS
і перевизначити методи XSToNative
і NativeToXS
. Дані методи конвертують строкове і бінарне представлення даних одне в одне.


Найбільш простим способом реалізації інтерфейсу на сервері є створення і реєстрація в invocation
реєстрі класу-спадкоємця від TInvokableClass
. Клас TInvokableClass
має дві чудові особливості:


· Invocation
реєстр знає про те, як створити екземпляр цього класу і його спадкоємців при запиті клієнтом викликів методів інтерфейсу;


· Оскільки клас TInvokableClass
є спадкоємцем від TInterfacedObject
, то він уміє звільнити пам'ять у разі, коли кількість посилань на нього дорівнює 0, що полегшує програмісту життя.


Текст модуля реалізації представлено далі:


unit u_Impl;


interface


uses InvokeRegistry, u_Intrf;


type


TEncodeDecode = class(TInvokableClass, IEncodeDecode)


protected


function EuroToUk(Value: Currency): Currency; stdcall;


function UkToEuro(Value: Currency): Currency; stdcall;


end;


implementation


{ TEncodeDecode }


function TEncodeDecode.UkToEuro(Value: Currency): Currency;


begin


Result := Value / 6.2;


end;


function TEncodeDecode.EuroToUk(Value: Currency): Currency;


begin


Result := Value * 6.2;


end;


initialization


InvRegistry.RegisterInvokableClass(TEncodeDecode);


end.


У випадку, якщо Ви не хочете успадковувати клас від TInvokableClass
, необхідно створити і зареєструвати метод-фабрику класу, який зможе створювати екземпляри класу. Метод повинен бути типу TCreateInstanceProc = procedure(out obj: TObject)
. При цьому екземпляр повинен уміти ліквідовувати себе, якщо кількість посилань використовуючих його клієнтів стане нульовою. При реєстрації такого класу методу InvRegistry.RegisterInvokableClass
другим параметром необхідно передати ім'я методу-фабрики класу.


Залишився останній крок - створення проекту прикладення. У RAD оберімо команду меню File | New | Other і із закладки WebServices
оберімо значок SOAP Server Application. Буде виведений діалог вибору формату прикладення Web Services (мал. 2
).



Малюнок 2


Оберімо формат CGI Stand-alone executable. При цьому буде створений проект з Web-модулем, що містить три компоненти: HTTPSoapDispatcher, HTTPSoapPascalInvoker, WSDLHTMLPublish (мал. 3
).



Малюнок 3


· HTTPSoapDispatcher одержує і обробляє SOAP-повідомлення
, перенаправляючи їх invoke інтерфейсам, зареєстрованим у прикладенні. Таким чином HTTPSoapDispatcher
є диспетчером, відповідальним за прийом, розподіл і відправку SOAP-повідомлень.
Інтерпретація запитів і виклик методів інтерфейсів здійснюється іншим компонентом, вказаним у властивості Dispatcher (HTTPSoapPascalInvoker1)
.


· HTTPSoapDispatcher
автоматично реєструє себе в Web-модулі, як автодиспетчуємий. При цьому всі запити передаються HTTPSoapDispatcher
, що позбавляє Вас від необхідності створювати оброблювачі запитів Web-модуля.


· WSDLHTMLPublish1
генерує і видає за запитом клієнта опис інтерфейсу сервера.


На запит про необхідність створення інтерфейсу необхідно клацнути по кнопці Yes (мал . 4.4
).



Малюнок 4


У вікні діалогу, яке з’явилося, треба задати ім’я служби (мал. 5
).



Малюнок 5


Далі в проект необхідно підключити файли з описом і реалізацією інтерфейсу. Для цього в RAD оберімо команду меню Project | Add to project і у діалозі, що з'явився, оберімо модулі з описом і реалізацією методів інтерфейсу (мал. 6
).



Малюнок 6


Тепер можна зберегти проект, побудувати його і розташувати одержаний виконуваний файл у каталозі c:InetpubScripts Web-сервера IIS. Сервер готовий до роботи.


Створення клієнта Web Services


Умовно розробку клієнта можна розділити на дві частини:


· Отримання опису інтерфейсу сервера;


· Написання коду виклику методів сервера.


У разі розробки сервера на Delphi
існує модуль з описом інтерфейсу сервера на мові Object Pascal
, т.ч перший етап може бути пропущений. У випадку якщо сервер був розроблений із використанням інших мов або модуль з описом інтерфейсу недоступний, необхідно одержати опис інтерфейсу у форматі WSDL
або XML
. Перший варіант – це попросити файл з описом у розроблювача, другий - згенерувати опис самому. Для цього досить запустити Web-браузер і в рядку адреси набрати команду: http://<ім’я сервера>/<папка Scripts>/< ім’я прикладення-сервера>/wsdl. У даному прикладі сервер розташовано на локально

му комп’ютері, як Web-сервер IIS
, тому рядок адреси виглядає так: http://localhost/Scripts/SOAPServerProject.exe/wsdl. При цьому на екран буде виведена таблиця з описом інтерфейсів сервера (мал. 7
).



Малюнок 7


Необхідно обрати в таблиці інтерфейс IEncodeDecode
,
що цікавить нас, при цьому буде згенеровано опис інтерфейсу у форматі XML:


<?xml version="1.0" encoding="utf-8" ?>


-<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="IEncodeDecodeservice" targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/">


-<message name="EuroToUk0Request">


<partname="Value" type="xs:double" />


</message>


-<message name="EuroToUk0Response">


<partname="return" type="xs:double" />


</message>


-<message name="UkToEuro1Request">


<partname="Value" type="xs:double" />


</message>


-<message name="UkToEuro1Response">


<partname="return" type="xs:double" />


</message>


-<portType name="IEncodeDecode">


-<operation name="EuroToUk">


<inputmessage="tns:EuroToUk0Request" />


<outputmessage="tns:EuroToUk0Response" />


</operation>


-<operation name="UkToEuro">


<inputmessage="tns:UkToEuro1Request" />


<outputmessage="tns:UkToEuro1Response" />


</operation>


</portType>


-<binding name="IEncodeDecodebinding" type="tns:IEncodeDecode">


<soap:bindingstyle="rpc" transport="http://schemas.xmlsoap.org/soap/http" />


-<operation name="EuroToUk">


<soap:operationsoapAction="urn:u_Intrf-IEncodeDecode#EuroToUk" style="rpc" />


-<input message="tns:EuroToUk0Request">


<soap:bodyuse="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:u_Intrf-IEncodeDecode" />


</input>


-<output message="tns:EuroToUk0Response">


<soap:bodyuse="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:u_Intrf-IEncodeDecode" />


</output>


</operation>


-<operation name="UkToEuro">


<soap:operationsoapAction="urn:u_Intrf-IEncodeDecode#UkToEuro" style="rpc" />


-<input message="tns:UkToEuro1Request">


<soap:bodyuse="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:u_Intrf-IEncodeDecode" />


</input>


-<output message="tns:UkToEuro1Response">


<soap:bodyuse="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:u_Intrf-IEncodeDecode" />


</output>


</operation>


</binding>


-<service name="IEncodeDecodeservice">


-<port name="IEncodeDecodePort" binding="tns:IEncodeDecodebinding">


<soap:addresslocation="http://localhost/Scripts/SOAPServerProject.exe/soap/IEncodeDecode" />


</port>


</service>


</definitions>


Збережіть його у файлі IEncodeDecode.xml. Отже, тим або іншим способом файл з описом у форматі XML опинився у нас в руках, тепер необхідно експортувати його в Delphi
. При експорті Delphi
згенерує модуль з описом інтерфейсу на мові Object Pascal
. Оберімо команду меню File | New | Other, перейдемо на закладку WebServices
і оберімо ікону WSDL Importer. При цьому на екрані з'явиться діалог імпорту опису (мал. 4.8
).


Використовуючи кнопку … діалогу, вкажемо одержаний раніше файл SOAPClient.xml, і натиснемо кнопку Finish. Модуль Delphi
з описом інтерфейсу готовий.



Малюнок 8


// ************************************************************************ //


// The types declared in this file were generated from data read from the


// WSDL File described below:


// WSDL : D:SOAPSOAPClientIEncodeDecode.xml


// Encoding : utf-8


// Version : 1.0


// (05.02.2006 10:06:04 - 1.33.2.5)


// ************************************************************************ //


unit IEncodeDecode1;


interface


uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;


type


// ************************************************************************ //


// The following types, referred to in the WSDL document are not being represented


// in this file. They are either aliases[@] of other types represented or were referred


// to but never[!] declared in the document. The types from the latter category


// typically map to predefined/known XML or Borland types; however, they could also


// indicate incorrect WSDL documents that failed to declare or import a schema type.


// ************************************************************************ //


// !:double - "http://www.w3.org/2001/XMLSchema"


// ************************************************************************ //


// Namespace : urn:u_Intrf-IEncodeDecode


// soapAction: urn:u_Intrf-IEncodeDecode#%operationName%


// transport : http://schemas.xmlsoap.org/soap/http


// style : rpc


// binding : IEncodeDecodebinding


// service : IEncodeDecodeservice


// port : IEncodeDecodePort


// URL : http://localhost/Scripts/SOAPServerProject.exe/soap/IEncodeDecode


// ************************************************************************ //


IEncodeDecode = interface(IInvokable)


['{2F701C83-3E4D-2403-7EA6-5BC2C987131C}']


function EuroToUk(const Value: Double): Double; stdcall;


function UkToEuro(const Value: Double): Double; stdcall;


end;


function GetIEncodeDecode(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IEncodeDecode;


implementation


function GetIEncodeDecode(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IEncodeDecode;


const


defWSDL = 'D:SOAPSOAPClientIEncodeDecode.xml';


defURL = 'http://localhost/Scripts/SOAPServerProject.exe/soap/IEncodeDecode';


defSvc = 'IEncodeDecodeservice';


defPrt = 'IEncodeDecodePort';


var


RIO: THTTPRIO;


begin


Result := nil;


if (Addr = '') then


begin


if UseWSDL then


Addr := defWSDL


else


Addr := defURL;


end;


if HTTPRIO = nil then


RIO := THTTPRIO.Create(nil)


else


RIO := HTTPRIO;


try


Result := (RIO as IEncodeDecode);


if UseWSDL then


begin


RIO.WSDLLocation := Addr;


RIO.Service := defSvc;


RIO.Port := defPrt;


end else


RIO.URL := Addr;


finally


if (Result = nil) and (HTTPRIO = nil) then


RIO.Free;


end;


end;


initialization


InvRegistry.RegisterInterface(TypeInfo(IEncodeDecode), 'urn:u_Intrf-IEncodeDecode', 'utf-8');


InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IEncodeDecode), 'urn:u_Intrf-IEncodeDecode#%operationName%');


end.


Переходимо до другого етапу - безпосередньому створенню клієнта. Створимо заготівку нового додатку командою File |New | Application. На головній формі розташуймо рядок введення, дві кнопки і компонент HTTPRIO
із закладки WebServices
(мал.
9
).



Малюнок 4.9


Компонент HTTPRIO призначений для виклику серверів через SOAP
. Вкажемо у властивості URL значення http://localhost/Scripts/SOAPServerProject.exe/soap/IEncodeDecode, - шлях до сервера. Далі включимо в проект модуль Delphi
з описом інтерфейсу сервера і вкажемо його в секції uses головної форми проекту.


Тепер можна переходити до написання коду виклику методів сервера. Оброблювачі подій натиснення на кнопки UkToEuro і EuroToUk виглядатимуть так:


procedure TForm1.UkToEuroClick(Sender: TObject);


var


X:IEncodeDecode;


R:Currency;


begin


X := HTTPRIO1 as IEncodeDecode;


R := X.UkToEuro(StrToCurr(Summa.Text));


ShowMessage(CurrToStr(R)+' €');


end;


procedure TForm1.EuroToUkClick(Sender: TObject);


var


X:IEncodeDecode;


R:Currency;


begin


X := HTTPRIO1 as IEncodeDecode;


R := X.EuroToUk(StrToCurr(Summa.Text));


ShowMessage(CurrToStr(R)+'Грн');


end;


Залишилося запустити проект на виконання і переконатися в його працездатності (мал. 10
).



Малюнок 10

Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

Название реферата: Технологія SOAP

Слов:1894
Символов:20903
Размер:40.83 Кб.