Пишемо SOAP клієнт-серверний додаток на PHP. WSDL файл: з чим це їдять? SoapUi

Заголовок топіка – це справді питання, т.к. я сам не знаю, що це і вперше спробую попрацювати з цим у рамках цієї статті. Єдине, що можу гарантувати, що код, поданий нижче, працюватиме, проте мої фрази будуть лише припущеннями та здогадками про те, як я сам усе це розумію. Отже, поїхали.

Вступ

Почати треба з того, навіщо створювалася концепція веб-сервісів. До моменту появи цього поняття у світі вже існували технології, що дозволяють програмам взаємодіяти на відстані, де одна програма могла викликати якийсь метод в іншій програмі, яка при цьому могла бути запущена на комп'ютері, розташованому в іншому місті чи навіть країні. Все це скорочено називається RPC (Remote Procedure Calling – віддалений виклик процедур). Як приклади можна навести технології CORBA, а Java – RMI (Remote Method Invoking – віддалений виклик методів). І начебто у них добре, особливо у CORBA, т.к. з нею можна працювати будь-якою мовою програмування, але чогось все ж таки не вистачало. Вважаю, що мінусом CORBA є те, що вона працює через якісь свої мережеві протоколизамість простого HTTP, який пролізе через будь-який firewall. Ідея веб-сервісу полягала у створенні такого RPC, який засовуватиметься в HTTP пакети. Так розпочалася розробка стандарту. Які у цього стандарту базові поняття:
  1. SOAP. Перш ніж викликати віддалену процедуру, потрібно описати цей виклик у XML файлі формату SOAP. SOAP - це просто одна з численних XML розміток, яка використовується у веб-сервісах. Все, що ми хочемо кудись відправити через HTTP, спочатку перетворюється на XML опис SOAP, потім засовується в HTTP пакет і посилається на інший комп'ютер у мережі TCP/IP.
  2. WSDL. Існує веб-сервіс, тобто. програма, методи якої можна віддалено викликати. Але стандарт вимагає, щоб до цієї програми додався опис, в якому сказано, що «так, ви не помилилися – це дійсно веб-сервіс і можна у нього викликати такі-то методи». Такий опис є ще одним файлом XML, який має інший формат, а саме WSDL. Тобто. WSDL – це просто XML-файл опису веб-сервісу і більше нічого.
Чому так стисло запитаєте ви? А детальніше не можна? Напевно, можна, але для цього доведеться звернутися до таких книг як Машнін Т. «Web-сервіси Java». Там протягом перших 200 сторінок йде детальний опискожного тегу стандартів SOAP та WSDL. Чи варто це робити? На погляд немає, т.к. все це на Java створюється автоматично, а вам потрібно лише написати вміст методів, які передбачається видалено викликати. Так ось у Java з'явився такий API, як JAX-RPC. Якщо хтось не знає, коли кажуть, що в Java є такий-то API, це означає, що є пакет з набором класів, які інкапсулюють технологію, що розглядається. JAX-RPC довго розвивався від версії до версії і зрештою перетворився на JAX-WS. WS, очевидно, означає WebService і можна подумати, що це просте перейменування RPC на популярне нині слівце. Це негаразд, т.к. Тепер веб-сервіси відійшли від початкового задуму і дозволяють не просто викликати віддалені методи, а й просто надсилати повідомлення-документи у форматі SOAP. Навіщо це потрібно я поки не знаю, навряд чи відповідь тут буде «про всяк випадок, раптом знадобиться». Сам би хотів дізнатися від досвідченіших товаришів. Та й останнє, далі з'явився ще JAX-RS для так званих RESTful веб-сервісів, але це тема окремої статті. У цьому вступ можна закінчувати, т.к. далі ми будемо вчитися працювати з JAX-WS.

Загальний підхід

У веб-сервісах завжди є клієнт та сервер. Сервер – це і є наш веб-сервіс і іноді його називають endpoint (типу як кінцева точка, куди доходять SOAP повідомлення від клієнта). Нам потрібно зробити таке:
  1. Описати інтерфейс нашого веб-сервісу
  2. Реалізувати цей інтерфейс
  3. Запустити наш веб-сервіс
  4. Написати клієнта та віддалено викликати потрібний метод веб-сервісу
Запуск веб-сервісу можна здійснювати різними способами: або описати клас з методом main та запустити веб-сервіс безпосередньо, як сервер, або задеплоїти його на сервер типу Tomcat або будь-який інший. У другому випадку ми самі не запускаємо новий сервер і не відкриваємо ще один порт на комп'ютері, а просто говоримо контейнеру сервлетів Tomcat, що «ми написали тут класи веб-сервісу, опублікуй їх, будь ласка, щоб усі, хто до тебе звернутися могли нашим веб-сервіс скористатися». Незалежно від способу запуску веб-сервісу, клієнт у нас буде той самий.

Сервер

Запустимо IDEA та створимо новий проект Create New Project. Вкажемо ім'я HelloWebServiceта натиснемо кнопку Next, далі кнопку Finish. В папці srcстворимо пакет ru.javarush.ws. У цьому пакеті створимо інтерфейс HelloWebService: package ru. javarush. ws; // Це інструкції, тобто. спосіб відзначити наші класи та методи, // як пов'язані з веб-сервісною технологією import javax. jws. WebMethod; import javax. jws. WebService; import javax. jws. soap. SOAPBinding; // кажемо, що наш інтерфейс працюватиме як веб-сервіс@WebService // говоримо, що веб-сервіс використовуватиметься для виклику методів@SOAPBinding (style = SOAPBinding. Style. RPC) public interface HelloWebService ( // Кажемо, що цей метод можна викликати віддалено@WebMethod public String getHelloString (String name) ; ) У цьому коді класи WebService і WebMethod є так званими інструкціями і нічого не роблять, крім як позначають наш інтерфейс та його метод, як веб-сервіс. Це саме стосується і класу SOAPBinding. Різниця лише в тому, що SOAPBinding – це інструкція з параметрами. У разі використовується параметр style зі значенням, що говорить, що веб-сервіс працюватиме через повідомлення-документи, бо як класичний RPC, тобто. для виклику методу. Давайте реалізуємо логіку нашого інтерфейсу та створимо у нашому пакеті клас HelloWebServiceImpl. До речі, зауважу, що закінчення класу на Impl – це угода Java, за якою так позначають реалізацію інтерфейсів (Impl – від слова implementation, тобто реалізація). Це не вимога і ви вільні назвати клас як хочете, але правила хорошого тону цього вимагають: package uk. javarush. ws; // Таже анотація, що і при описі інтерфейсу, import javax. jws. WebService; // Але тут використовується з параметром endpointInterface, // вказівним повне ім'якласу інтерфейсу нашого веб-сервісу@WebService (endpointInterface = "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implements HelloWebService ( @Override public String getHelloString (String name) ( // просто повертаємо вітання return "Hello, "+name+"!" ; ) ) Запустимо наш веб-сервіс як самостійний сервер, тобто. без участі будь-яких Tomcat та серверів додатків (це тема окремої розмови). Для цього у структурі проекту у папці srcстворимо пакет ru.javarush.endpoint, а в ньому створимо клас HelloWebServicePublisher з методом main: package ru. javarush. endpoint; // клас для запуску веб-сервера з веб-сервісами import javax. xml. ws. Endpoint; // клас нашого веб-сервісу import uk. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher ( public static void main (String. . . args) ( // запускаємо веб-сервер на порту 1986 // і за адресою, вказаною в першому аргументі, // запускаємо веб-сервіс, що передається у другому аргументі Endpoint. publish ( "http://localhost:1986/wss/hello", New HelloWebServiceImpl()); ) ) Тепер запустимо цей клас, натиснувши Shift+F10. У консолі нічого не з'явиться, але сервер запущено. У цьому можна переконатися, набравши в браузері рядок http://localhost:1986/wss/hello?wsdl . Сторінка, що відкрилася, з одного боку, доводить, що у нас на комп'ютері (localhost) запустився веб-сервер (http://) на порту 1986, а, з іншого боку, показує WSDL опис нашого веб-сервісу. Якщо ви зупините програму, то опис стане недоступним, як і сам веб-сервіс, тому робити цього не будемо, а перейдемо до написання клієнта.

Клієнт

У папці проекту srcстворимо пакет ru.javarush.client, а в ньому клас HelloWebServiceClient з методом main: package ru. javarush. client; // Потрібно, щоб отримати wsdl опис і через нього // Дотягнутися до самого веб-сервісу import java. net. URL; // такий ексепшн виникне під час роботи з об'єктом URL import java. net. MalformedURLEвідповідь; // класи, щоб пропарсувати xml-ку c wsdl описом // і дотягнутися до тега service в ньому import javax. xml. namespace. QName; import javax. xml. ws. Service; // інтерфейс нашого веб-сервісу (нам більше і потрібно) import uk. javarush. ws. HelloWebService; public class HelloWebServiceClient ( public static void main (String args) throws MalformedURLException ( // створюємо посилання на wsdl опис URL url= new URL ( "http://localhost:1986/wss/hello?wsdl") ; // Параметри наступного конструктора дивимося в першому тезі WSDL опису - definitions // Перший аргумент дивимося в атрибуті targetNamespace // Другий аргумент дивимося в атрибуті name QName qname = new QName ("http://ws.javarush.ru/", "HelloWebServiceImplService"); // Тепер ми можемо дотягнутися до тега service у wsdl описі, Service service = Service. create (url, qname); // а далі і до вкладеного в нього тега port, щоб // отримати посилання на віддалений від нас об'єкт веб-сервісу HelloWebService hello=service. getPort (HelloWebService. class); // Ура! Тепер можна викликати віддалений метод System. out. println (hello. getHelloString ("JavaRush")); ) ) Максимум коментарів за кодом я дав у лістингу. Додати мені нічого, тому запускаємо (Shift+F10). Ми повинні у консолі побачити текст: Hello, JavaRush! Якщо не побачили, то мабуть забули запустити веб-сервіс.

Висновок

У цьому топіці був представлений короткий екскурс до веб-сервісів. Ще раз скажу, що багато з того, що я написав – це мої здогади щодо того, як це працює, і тому мені не варто довіряти. Буду вдячний, якщо знаючі люди мене виправлять, адже тоді я чогось навчуся. UPD.

Мова опису Web-сервісів (WSDL)

В останніх прикладах ви могли бачити окремі фрагменти WSDL-коду. Нагадаємо, що WSDL - це заснована на XML граматика, призначена для опису можливостей взаємодії зовнішніх клієнтів з Web-методами, доступними за цією адресою URL в рамках кожного з протоколів зв'язку, що підтримуються. Багато в чому WSDL-документ може розглядатися як "контракт" між клієнтом Web-сервісу і самим Web-сервісом. Це ще одна метамова. Зокрема, WSDL використовується для опису наступних характеристик будь-якого доступного Web-методу:

Ім'я Web-методу XML;

Число, тип і порядок дотримання параметрів (якщо такі є);

Тип значення, що повертається (якщо таке передбачено);

Умови виклику HTTP GET, HTTP POST та SOAP.

У більшості випадків документи WSDL генеруються автоматично відповідним Web-сервером. Нагадаємо, що при додаванні суфікса?

http://locаlhost/SomeWS/theWS.asmx?wsdl

Але якщо IIS автоматично генерує WSDL-документ для даного Web-сервісу XML, навіщо тоді потрібне глибоке розуміння синтаксису генерованих WSDL-даних? Відповідь зазвичай залежить від того, як ваш сервіс використовуватиметься зовнішніми програмами. У разі Web-сервісів XML, призначених для "внутрішнього" використання, згенерованого Web-сервером WSDL-коду буде, як правило, достатньо.

Між тим. Цілком можливо розпочати розробку Web-сервісу XML із створення WSDL-документа вручну (про це вже говорилося вище). Головна ідея початку розробки зі створення документа WSDL пов'язана з питаннями сумісності. Згадайте, що до появи специфікації WSI різні інструменти побудови Web-сервісів часто генерували несумісні WSDL-описи. Якщо розпочинати розробку з WSDL-коду, ви можете побудувати документ так, як потрібно.

Як ви можете здогадатися, для початку розробки Web-сервісу XML із створення WSDL-документа потрібно дуже добре знання граматики WSDL, обговорення якої в контексті цього розділу не передбачено. Але ми розглянемо базову структуру документа WSDL. Розібравшись в основах, ви зможете оцінити користь утиліти командного рядка wsdl.exe.

Зауваження.Найсвіжішу інформацію про мову WSDL можна знайти на сторінках http://www.w3.org/tr/wsdl.

Визначення документа WSDL

Документ WSDL відкривається і закривається кореневим елементом ‹definitions›. У дескрипторі, що відкриває, зазвичай визначаються різні атрибути xmlns. Вони задають простір імен XML, що визначають різні підлеглі елементи. Як мінімум, елемент ‹definitions› має вказати простір імен, де визначені самі елементи WSDL (http://schemas.xmlsoap.org/wsdl). Для того щоб бути корисним, дескриптор ‹definitions›, що відкриває, повинен, крім того, вказати простори імен XML, що визначають прості типиданих WSDL, типи XML-схеми, елементи SOAP, і навіть цільовий простір імен. Наприклад, ось як виглядає розділ для нашого Web-сервісу калькулятора.

‹wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"

xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns-mime="http://schemas.xmlsoap.org/wsdl/mime/"

xmlns:tns="http://www.IntertechTraining.com/"

xmlns:s="http://www.w3.org/2001/XMLSchema"

xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"

xmlns:http="http://schemes.xmlsoap.оrg/wsdl/http/"

targetNamespace="http://www.IntertechTraining.com/"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"›

‹/wsdl:definitions›

У контексті кореневого елемента можна знайти п'ять підлеглих елементів. Загальний вигляд документа WSDL повинен бути приблизно таким.

‹?xml version="1.0" encoding="utf-8"?›

‹wsdl:definitions …›

‹wsdl:types›

‹!-- Список типів, доступних для цього Web-сервісу --›

‹wsdl:/types›

‹wsdl:message›

‹!-- Формат повідомлень --›

‹wsdl:/message›

‹wsdl:portType›

‹!-- Інформація портів --›

‹wsdl:/portType›

‹wsdl:binding›

‹!-- Інформація зв'язування --›

‹wsdl:/binding›

‹wsdl:service›

‹!-– Інформація про сам Web-сервіс XML --›

‹wsdl:/service›

‹wsdl:/definitions›

Як і слід очікувати, кожен із цих підлеглих елементів міститиме додаткові елементи та атрибути, що уточнюють опис наявних можливостей. Давайте по черзі розглянемо найважливіші з допустимих вузлів.

Елемент ‹types›

Спочатку ми розглянемо елемент ‹types›, який містить описи всіх типів даних, пропонованих Web-сервісом. Ви, можливо, знаєте, що мова XML сама визначає ряд "базових" типів даних, і всі вони визначені в рамках простору імен XML http://www.w3.org/2001/XMLSchema (який має бути вказаний у контексті кореневого елемента ‹ definitions›). Візьмемо, наприклад, метод Subtract() нашого Web-сервісу калькулятора, що має два вхідні параметри цілісного типу. У термінах WSDL тип System.Int32 середовища CLR описується у контексті елемента ‹complexType›.

‹s:еlement name= "Subtract"›

‹s:sequence›

‹s:element minOccurs=" 1 " maxOccurs=" 1 " name=" x" type=" s:int" /›

‹s:element minOccurs="" 1 " maxOccurs=" 1 " name=" y" type=" s:int" /›

‹/ s:sequence›

‹/s:complexType›

‹/s:element›

Ціле число, яке повертається методом Subtract(), також описується в рамках елемента types.

‹s:element name= " SubtractResponse"›

‹s:complexType›

‹s:sequence›

‹s:element minOccurs=" 1 " maxOccurs = " 1 " name=" SubtractResult" type=" s:int"/›

‹/s:sequence›

‹ /s:complexType›

‹/s:element›

Якщо ви маєте Web-метод, який повертає або отримує користувальницькі типиданих, вони також з'являться у контексті елемента ‹complexType›. Деталі того, як за допомогою Web-методу зробити доступними типи даних.NET, ми розглянемо пізніше. Наприклад припустимо, що ви визначили Web-метод, який повертає структуру з ім'ям Point.

public struct Point (

public string pointName;

WSDL-опис для цієї "складної структури" виглядатиме приблизно так.

‹s:complexType name=" Point"›

‹s:sequence›

‹s:element minOccurs=" 1 " maxOccurs=" 1 " name=" x" type=" s:int" /›

‹s:element minOccurs=" 1 "" maxOccurs=" 1 " name=" y" type= " s:int" /›

‹s:element minOccurs=" 0 " maxOccurs=" 1 " name=" рointName" type=" s:string" /›

‹/s:sequence›

‹/s:complexType›

Елемент ‹message›

Елемент ‹message› використовується для визначення формату обміну запитами та відповідями даного Web-методу. Оскільки один Web-сервіс дозволяє передачу безлічі повідомлень між відправником і одержувачем, одному документу WSDL дозволяється визначати безліч елементів ‹message›. Як правило, у цих визначеннях використовуються типи, зазначені в рамках елемента .

Незалежно від кількості елементів ‹message›, визначених у документі WSDL, вони зазвичай є парами. Перше визначення являє собою вхідний формат повідомлення, а друге – вихідний формат того ж повідомлення. Наприклад, метод Subtract() Web-сервісу CalculatorWebService визначає наступні елементи‹message›.

‹wsdl:message name=" SubtractSoapIn"›

‹wsdl:part name="parameters" element="tns:Subtract" /›

‹/wsdl:message›

‹wsdl: message name=" SubtractSoapOut"›

‹wsdl:part name="parameters" element="tns:SubtractResponse" /›

‹/wsdl:message›

Тут ви бачите лише зв'язок SOAP відповідного сервісу. Як говорилося на початку цього розділу, Web-сервіси XML можуть викликатися за допомогою SOAP або HTTP-методів GET та POST. Але якщо ви дозволите зв'язок HTTP POST (відповідні пояснення будуть запропоновані пізніше), WSDL-код, що генерується, повинен продемонструвати наступні дані ‹message›.

‹wsdl: message name=" SubtractHttpPostIn"›

‹part name="n1" type="s:string" /›

‹part name="n2" type="s:string" /›

‹wsdl:/message›

‹wsdl:message name=" SubtractHttpPostOut"›

‹part name="Body" element="s0:int" /›

‹wsdl:/message›

Елементи «message» самі по собі не надто корисні. Однак ці визначення повідомлень посилаються інші частини WSDL-документа.

Зауваження.Не всі Web-методи вимагають і запиту, і відповіді. Якщо Web-метод є "одностороннім", йому необхідний лише елемент ‹message› запиту. Позначити Web-метод як односторонній можна за допомогою атрибута .

Елемент ‹portType›

Елемент ‹portType› визначає різні зв'язки, які можуть виникати між клієнтом та сервером, і кожен такий зв'язок представляється вкладеним елементом ‹operation›. Нескладно здогадатися, що типовими операціями тут мають бути SOAP, HTTP GET і HTTP POST. Проте й інші операції. Наприклад, одностороння операція дозволяє клієнту відправити повідомлення даному Web-серверу, але не отримати відповідь (це схоже на виклик методу без очікування значення, що повертається). Операція "вимога-відповідь" дозволяє серверу відправити запит під час відповіді клієнта (що можна розглядати як доповнення операції "запит-відповідь").

Щоб проілюструвати формат необов'язкового вкладеного елемента ‹operation›, розглянемо визначення WSDL для методу Subtract().

‹wsdl portType name= "CalculatorWebServiceSoap"›

‹wsdl:operation name=" Subtract"›

‹wsdl:input message=" tns:SubtractSoapIn" /›

‹wsdl:output message=" tns:SubtractSoapOut" /›

‹ /wsdl:operation›

‹wsdl:/portType›

Зверніть увагу на те, як елементи ‹input› та ‹output› посилаються на відповідне ім'я повідомлення, визначене в рамках елемента ‹message›. Якби для методу Subtract() було дозволено HTTP-метод POST, ви побачили б наступний додатковий елемент‹operation›.

‹wsdl:portType name="CalculatorWebServiceHttpPost"›

‹wsdl:input message=" s0:SubtractHttpPostIn" /›

‹wsdl:output message=" s0:SubtractHttpPostOut" /›

‹ wsdl:/operation›

‹wsdl:/portType›

Нарешті, врахуйте те, що якщо даний Web-метод описаний за допомогою властивості Description, елемент ‹operation› міститиме вкладений елемент ‹documentation›.

Елемент ‹binding›

Цей елемент вказує на точний формат обміну GET, POST і SOAP. Це "багатослівний" з усіх елементів, що містяться в контексті кореневого елемента . Ось, наприклад, визначення елемента binding з описом того, як сторона, що викликає, може взаємодіяти з Web-методом MyMethod(). використовуючи SOAP.

‹wsdl:binding name="CalculatorWebServiceSoap12" type=" tns:CalculatorWebServiceSoap"›

‹soap12:binding transport=" http://schemas.xmlsoap.org/soap/http" /›

‹wsdl:operation name= " Subtract"›

‹soap12:operation soapAction=" http://www.IntertechTraining.com/Subtract" style="document" /›

‹wsdl:input›

‹soap12:body use=" literal" /›

‹/wsdl:input›

‹wsdl:output›

‹soap12:body use=" literal" /›

‹/wsdl:output›

‹/wsdl:operation›

‹/wsdl:binding›

Елемент ‹service›

Нарешті, ми маємо елемент ‹service›, який вказує характеристики самого Web-сервісу (наприклад, його URL). Головним завданням цього елемента є опис багатьох портів, відкритих даним Web-сервером. Для цього елемент ‹services› може використовувати будь-яку кількість вкладених елементів ‹port› (не плутайте їх із елементом ‹portType›). Ось як виглядає елемент ‹service› для CalculatorWebService.

‹wsdl:service name= "CalculatorWebService"›

‹wsdl:documentation xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"›

Чудовий Web-сервіс калькулятора

‹/wsdl:documentation›

‹wsdl:port name= "CalculatorWebServiceSoap" binding= "tns:CalculatorWebServiceSoap"

‹soap:address location= "http://localhost:1109/CalculatorWebService/ Service.asmx"/›

‹/wsdl:port›

‹wsdl:port name="CalculatorWebServiceSoap12" binding = " tns:CalculatorWebServiceSoap12"›

‹soap12:address location= "http://localhost:1109/CalculatorWebService/Service.asmx"/›

‹/wsdl:port›

‹/wsdl:service›

Отже, як бачите, WSDL-код, що автоматично повертається сервером ITS, не є надскладним, але оскільки WSDL є граматикою на основі XML, цей код досить "багатословний". Тим не менш, тепер ви повинні краще розуміти роль WSDL, так що давайте розглянемо трохи детальніше протоколи зв'язку Web-сервісів XML.

Зауваження.Нагадаємо, що простір імен System.Web.Services.Description містить безліч типів, які дозволяють програмно читати та обробляти "сирий" WSDL-код (можете перевірити самі, якщо вас це цікавить).

Веб-сервіси є технологією інтеграції додатків, яка може використовуватися в Internet. Як приклад можливого використання веб-сервісів розглянемо планування подорожей. Зазвичай у такій ситуації потрібні: замовлення квитків на літак, бронювання місць у готелі, оренда автомобіля та, можливо, використання послуг місцевих компаній, які організовують екскурсії.

Традиційно використовуючи Internet, вам доведеться відвідати сервер авіакомпанії, сервер готелю чи мережі готелів, сервер компанії з оренди автомобілів та сервер компанії, що спеціалізується на організації екскурсій у вибраному вами місці. Всі ці дії можуть зайняти досить багато часу, перш ніж ви досягнете мети. І при цьому жодна із задіяних вами компаній не знатиме, які ваші плани, а отже, не зможе оптимізувати ваш час. Проблема полягає в тому, що компанії, що спеціалізуються на окремих областях - авіа, готельній, прокаті автомобілів і т.п., у більшості випадків замкнуті самі на себе та використовують власні засоби зберігання та подання даних.

Більш зручно було б запустити додаток, який би прийняв від вас необхідну інформацію та виконав усі рутинні дії – замовлення квитків, бронювання готелю тощо – автоматично, без вашої участі. Щоб це стало можливим, ви маєте використовувати веб-сервіси. Давайте розглянемо, що зміниться у разі.

Припустимо, авіакомпанія надає веб-сервіс, що дозволяє програмам отримувати список рейсів між двома містами для заданої дати. У цьому випадку більше не потрібно звертатися до веб-сайту авіакомпанії та вказувати різні критерії пошуку - вся необхідна інформація доступна у вигляді єдиного документа XML. Тепер припустимо, що авіакомпанія, готель та агенція з прокату автомобілів надають веб-сервіси, що дозволяють програмно купувати квитки, бронювати номери та орендувати автомобілі. У цьому випадку можна об'єднати виклики всіх цих сервісів в єдину програму, яка зможе виконати всю рутинну роботу без участі користувача.

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

Крім очевидного підвищення якості обслуговування клієнтів, використання веб-сервісів має безліч інших переваг. Наприклад, якщо агентство прокату автомобілів знає, що ваш рейс затримується, воно може гнучкіше розпорядитися своїми автомобілями. У міру зростання кількості веб-сервісів ми зможемо побачити комплексніші приклади їх використання. Проте слід зазначити, що впровадження концепції веб-сервісів вимагає не лише перегляду багатьох бізнес-правил та схем взаємодії між галузями та секторами тієї чи іншої галузі, а й підвищення безпеки обміну даними.

Розглянувши практичне застосування веб-сервісів, звернімося до стандартів, які лежать в основі цих сервісів.

стандарти

Як ми знаємо, основу веб-сервісів лежать Internet-стандарты. Ці стандарти визначають протоколи, а чи не способи реалізації. Таке твердження є запорукою успіху Internet - жодна компанія неспроможна проводити Internet-стандарты і ставити власні правила гри. Наприклад, стандарти веб-сервісів розробляються спільно такими компаніями, як IBM, Microsoft, Ariba та іншими, і обговорюються комітетом World Wide Web Consortium (W3C).

Веб-сервіси базуються на трьох основних веб-стандартах:

SOAP (Simple Object Access Protocol) - протокол для надсилання повідомлень за протоколом HTTP та іншим Internet-протоколам;

WSDL (Web Services Description Language) – мова для опису програмних інтерфейсів веб-сервісів;

UDDI (Universal Description, Discovery and Integration) – стандарт для індексації веб-сервісів.

Сервери програм є сховищами веб-сервісів і роблять їх доступними через протоколи HTTP GET, HTTP POST та HTTP SOAP.

Існуючі веб-сервіси описуються в WSDL-документах, які розміщуються або на сервері додатків, або у спеціальних XML-сховищах. WSDL-документ може посилатися на інші WSDL-документи та документи XSD (XML Schema), в яких описані типи даних, які використовуються веб-сервісами. XML-сховища використовуються для керування документами WSDL. Всередині документа WSDL знаходиться адреса (URL) веб-сервісу. Веб-сервіси описані та проіндексовані у бізнес-реєстрі, що містить адреси (URL) WSDL-документів.

У наступних розділах ми розглянемо три основні веб-стандарти, на яких базуються веб-сервіси – SOAP, WSDL та UDDI – більш детально.

SOAP - Simple Object Access Protocol

SOAP - це стандарт для відсилання та отримання повідомлень через Internet. Спочатку цей протокол був запропонований фірмою Microsoft як засіб для віддаленого виклику процедур (RPC, Remote Procedure Call) за протоколом HTTP, а специфікація SOAP 1.0 (Userland, Microsoft, Developmentor) була тісно пов'язана з Component Object Model. Фірма IBM та низка інших компаній, у тому числі Lotus, зробили певний внесок у розвиток цього протоколу, та його специфікація була спрямована на розгляд комітетом W3C.

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

SOAP-повідомлення бувають двох типів: запит (Request) та відповідь (Response). Запит викликає метод віддаленого об'єкта, відповідь повертає результат виконання цього методу. Наведемо приклад запиту у форматі SOAP:







HST


А ось відповідь:



xmlns:SOAP-ENV="http:///envelope"
SOAP-ENV:encodingStyle="http:///encoding//"


48.6


Специфікація SOAP визначає формат кодування, який, у свою чергу, задає спосіб представлення даних у форматі XML.

WSDL - Web Services Description Language

Для того, щоб програми могли використовувати веб-сервіси, програмні інтерфейси останніх повинні бути детально описані - з цієї точки зору мова WSDL відіграє ту ж роль, що і мова Interface Definition Language (IDL) у розподілених обчисленнях. Опис може включати таку інформацію, як протокол, адресу сервера, номер порту, список доступних операцій, формат запиту і відповіді тощо.

Для опису цієї інформації було запропоновано кілька мов. Одним з них була мова Service Description Language (SDL), розроблена Microsoft і входила в першу версію Microsoft SOAP Toolkit. IBM переробила специфікацію і, використовуючи специфікацію Network Accessible Service Specification Language (NASSL), випустила NASSL Toolkit як частину SOAP4J. Ідеї, реалізовані в NASSL, вплинули специфікацію мови SOAP Contract Language (SCL), запропоновану Microsoft. В даний час обидві специфікації (NASSL і SDL/SCL), а також пропозиції інших фірм враховані специфікації мови WSDL. Для опису бізнес-логіки IBM та Microsoft працюють над специфікацією мови Web Services Flow Language (WSFL). Ось приклад скелета опису сервісів мовою WSDL:


xmlns:soap="http://(soaporg)/wsdl/soap"
xmlns="http://(soaporg)/wsdl/">

...

...
...


...
...


...

Як бачимо, опис сервісів є XML-документ, що з кількох елементів, зокрема з опису простору імен (namespace), описи типів і елементів, повідомлень, порту, і навіть можливих операцій - запитів і відповідей.

UDDI - Universal Description, Discovery and Integration

Завдання UDDI – надати механізм для виявлення веб-сервісів. UDDI задає бізнес-реєстр, в якому провайдери веб-сервісів можуть реєструвати сервіси, а розробники шукати необхідні їм сервіси. Компанії IBM, Microsoft і Ariba створили власні реєстри UDDI (незабаром ці реєстри будуть об'єднані в веб-реєстр), в одному з яких розробники можуть зареєструвати свої веб-сервіси, після чого дані будуть автоматично репліковані в інші реєстри.

UDDI базується на елементах чотирьох типів: Business Entity, Business Service, Binding Template та Technology Model.

Елемент Business Entity визначає індустрію, що надає цей веб-сервіс. Цей елемент може включати описи категорій для цієї промисловості, що полегшують детальніший пошук сервісів.

Business Service – це клас сервісів у межах певної галузі промисловості чи послуг. Кожна галузь належить певному елементу Business Entity.

Водночас Binding Template та Technology Model визначають веб-сервіс. Technology Model містить абстрактний опис, а Binding Template – конкретну специфікацію сервісу. Кожен елемент Binding Template належить певному елементу Business Service, але кілька елементів Binding Template можуть посилатися однією елемент Technology Model.

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

Реферат слухача ІКСІ, науковий керівник – Сергій Кунегін

У цій статті я розповім, що таке WSDL-файл, навіщо він потрібен і як з ним працювати.

Карта статті

Що таке WSDL

WSDL – це мова опису веб-сервісу, що має структуру XML. Основне призначення WSDL-файлу - це інтерфейс доступу до функцій сервісу, типів даних, що повертаються; шлях до сервера, який обробляє запити тощо.

Шлях до wsdl-файлу зазвичай має вигляд http://host/services/wsdl/gbdar-v2-2.wsdl

Існує безліч інструментів бібліотек, призначених для читання WSDL-файлу.

SoapUi

Одним з таких інструментів є soapUi(). Встановивши дистрибутив, призначений для вашої платформи, ви зможете створити новий проект командою File/New SoapUi project. У діалозі створення нового проекту залишаємо увімкненою галочку Create sample requests

Виконання запитів

У новому проекті будуть автоматично створені шаблони запитів для сервісу, опис якого міститься у файлі wsdl. Зліва в дереві Ви побачите перелік функцій, що містяться у файлі WSDL. Я розкрию функцію Replication. Всередині неї є запит Request1, двічі клацнувши по якому, ми побачимо діалог із шаблоном запиту, замість параметрів за промовчанням будуть проставлені знаки питання. Щоб функція коректно виконалася, необхідно заповнити всі параметри, які не позначені тегом Optional, після чого натиснути зелений трикутник у верхньому лівому куті діалогу.

Якщо всі параметри вказані правильно, справа відобразиться відповідь сервісу на запит.

SoapUi надає можливість перегляду параметрів WSDL-файлу, для цього необхідно двічі клацнути по найменуванню інтерфейсу (позначений зеленою іконкою в дереві WSDL-файлу, у мене gdbar-v2-2SOAP). У діалоговому вікні можна знайти:

  • Вкладка OverView — опис загальних параметрів WSDL, список функцій та пов'язаних з ними дій сервера
  • Вкладка Service Endpoints шлях до сервера та інші параметри
  • WSDL Content - дерево навігації по файлу
  • WS-I Compliance — тут можна створити WS-I звіт з інтерфейсу

Генерація документації

SoapUi дозволяє нам генерувати документацію щодо функцій WSDL. Для цього клацніть правою кнопкою по інтерфейсу та викличте команду Generate Documentation.В результаті отримаємо докладний мануал у html-форматі.

На цьому все, підписуйтесь на нові записи, залишайте коментарі, вносьте пропозиції щодо покращення статті.

Заголовок топіка – це справді питання, т.к. я сам не знаю, що це і вперше спробую попрацювати з цим у рамках цієї статті. Єдине, що можу гарантувати, що код, поданий нижче, працюватиме, проте мої фрази будуть лише припущеннями та здогадками про те, як я сам усе це розумію. Отже, поїхали.

Вступ

Почати треба з того, навіщо створювалася концепція веб-сервісів. До моменту появи цього поняття у світі вже існували технології, що дозволяють програмам взаємодіяти на відстані, де одна програма могла викликати якийсь метод в іншій програмі, яка при цьому могла бути запущена на комп'ютері, розташованому в іншому місті чи навіть країні. Все це скорочено називається RPC (Remote Procedure Calling – віддалений виклик процедур). Як приклади можна навести технології CORBA, а Java – RMI (Remote Method Invoking – віддалений виклик методів). І начебто у них добре, особливо у CORBA, т.к. з нею можна працювати будь-якою мовою програмування, але чогось все ж таки не вистачало. Вважаю, що мінусом CORBA є те, що вона працює через якісь свої мережеві протоколи замість простого HTTP, який пролізе через будь-який firewall. Ідея веб-сервісу полягала у створенні такого RPC, який засовуватиметься в HTTP пакети. Так розпочалася розробка стандарту. Які у цього стандарту базові поняття:
  1. SOAP. Перш ніж викликати віддалену процедуру, потрібно описати цей виклик у XML файлі формату SOAP. SOAP – це просто одна з численних розміток XML, яка використовується у веб-сервісах. Все, що ми хочемо кудись відправити через HTTP, спочатку перетворюється на XML опис SOAP, потім засовується в HTTP пакет і посилається на інший комп'ютер у мережі TCP/IP.
  2. WSDL. Існує веб-сервіс, тобто. програма, методи якої можна віддалено викликати. Але стандарт вимагає, щоб до цієї програми додався опис, в якому сказано, що «так, ви не помилилися – це дійсно веб-сервіс і можна у нього викликати такі-то методи». Такий опис є ще одним файлом XML, який має інший формат, а саме WSDL. Тобто. WSDL – це просто XML-файл опису веб-сервісу і більше нічого.
Чому так стисло запитаєте ви? А детальніше не можна? Напевно, можна, але для цього доведеться звернутися до таких книг як Машнін Т. «Web-сервіси Java». Там протягом перших 200 сторінок йде докладний опис кожного стандартного тега SOAP і WSDL. Чи варто це робити? На погляд немає, т.к. все це на Java створюється автоматично, а вам потрібно лише написати вміст методів, які передбачається видалено викликати. Так ось у Java з'явився такий API, як JAX-RPC. Якщо хтось не знає, коли кажуть, що в Java є такий-то API, це означає, що є пакет з набором класів, які інкапсулюють технологію, що розглядається. JAX-RPC довго розвивався від версії до версії і зрештою перетворився на JAX-WS. WS, очевидно, означає WebService і можна подумати, що це просте перейменування RPC на популярне нині слівце. Це негаразд, т.к. Тепер веб-сервіси відійшли від початкового задуму і дозволяють не просто викликати віддалені методи, а й просто надсилати повідомлення-документи у форматі SOAP. Навіщо це потрібно я поки не знаю, навряд чи відповідь тут буде «про всяк випадок, раптом знадобиться». Сам би хотів дізнатися від досвідченіших товаришів. Та й останнє, далі з'явився ще JAX-RS для так званих RESTful веб-сервісів, але це тема окремої статті. У цьому вступ можна закінчувати, т.к. далі ми будемо вчитися працювати з JAX-WS.

Загальний підхід

У веб-сервісах завжди є клієнт та сервер. Сервер – це і є наш веб-сервіс і іноді його називають endpoint (типу як кінцева точка, куди доходять SOAP повідомлення від клієнта). Нам потрібно зробити таке:
  1. Описати інтерфейс нашого веб-сервісу
  2. Реалізувати цей інтерфейс
  3. Запустити наш веб-сервіс
  4. Написати клієнта та віддалено викликати потрібний метод веб-сервісу
Запуск веб-сервісу можна проводити різними способами: або описати клас з методом main і запустити веб-сервіс безпосередньо, як сервер, або задеплоїти його на сервер типу Tomcat або будь-який інший. У другому випадку ми самі не запускаємо новий сервер і не відкриваємо ще один порт на комп'ютері, а просто говоримо контейнеру сервлетів Tomcat, що «ми написали тут класи веб-сервісу, опублікуй їх, будь ласка, щоб усі, хто до тебе звернутися могли нашим веб-сервіс скористатися». Незалежно від способу запуску веб-сервісу, клієнт у нас буде той самий.

Сервер

Запустимо IDEA та створимо новий проект Create New Project. Вкажемо ім'я HelloWebServiceта натиснемо кнопку Next, далі кнопку Finish. В папці srcстворимо пакет ru.javarush.ws. У цьому пакеті створимо інтерфейс HelloWebService: package ru. javarush. ws; // Це інструкції, тобто. спосіб відзначити наші класи та методи, // як пов'язані з веб-сервісною технологією import javax. jws. WebMethod; import javax. jws. WebService; import javax. jws. soap. SOAPBinding; // кажемо, що наш інтерфейс працюватиме як веб-сервіс@WebService // говоримо, що веб-сервіс використовуватиметься для виклику методів@SOAPBinding (style = SOAPBinding. Style. RPC) public interface HelloWebService ( // Кажемо, що цей метод можна викликати віддалено@WebMethod public String getHelloString (String name) ; ) У цьому коді класи WebService і WebMethod є так званими інструкціями і нічого не роблять, крім як позначають наш інтерфейс та його метод, як веб-сервіс. Це саме стосується і класу SOAPBinding. Різниця лише в тому, що SOAPBinding – це інструкція з параметрами. У разі використовується параметр style зі значенням, що говорить, що веб-сервіс працюватиме через повідомлення-документи, бо як класичний RPC, тобто. для виклику методу. Давайте реалізуємо логіку нашого інтерфейсу та створимо у нашому пакеті клас HelloWebServiceImpl. До речі, зауважу, що закінчення класу на Impl – це угода Java, за якою так позначають реалізацію інтерфейсів (Impl – від слова implementation, тобто реалізація). Це не вимога і ви вільні назвати клас як хочете, але правила хорошого тону цього вимагають: package uk. javarush. ws; // Таже анотація, що і при описі інтерфейсу, import javax. jws. WebService; // Але тут використовується з параметром endpointInterface, // вказує повне ім'я класу інтерфейсу нашого веб-сервісу@WebService (endpointInterface = "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implements HelloWebService ( @Override public String getHelloString (String name) ( // просто повертаємо вітання return "Hello, "+name+"!" ; ) ) Запустимо наш веб-сервіс як самостійний сервер, тобто. без участі будь-яких Tomcat та серверів додатків (це тема окремої розмови). Для цього у структурі проекту у папці srcстворимо пакет ru.javarush.endpoint, а в ньому створимо клас HelloWebServicePublisher з методом main: package ru. javarush. endpoint; // клас для запуску веб-сервера з веб-сервісами import javax. xml. ws. Endpoint; // клас нашого веб-сервісу import uk. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher ( public static void main (String. . . args) ( // запускаємо веб-сервер на порту 1986 // і за адресою, вказаною в першому аргументі, // запускаємо веб-сервіс, що передається у другому аргументі Endpoint. publish ( "http://localhost:1986/wss/hello", New HelloWebServiceImpl()); ) ) Тепер запустимо цей клас, натиснувши Shift+F10. У консолі нічого не з'явиться, але сервер запущено. У цьому можна переконатися, набравши в браузері рядок http://localhost:1986/wss/hello?wsdl . Сторінка, що відкрилася, з одного боку, доводить, що у нас на комп'ютері (localhost) запустився веб-сервер (http://) на порту 1986, а, з іншого боку, показує WSDL опис нашого веб-сервісу. Якщо ви зупините програму, то опис стане недоступним, як і сам веб-сервіс, тому робити цього не будемо, а перейдемо до написання клієнта.

Клієнт

У папці проекту srcстворимо пакет ru.javarush.client, а в ньому клас HelloWebServiceClient з методом main: package ru. javarush. client; // Потрібно, щоб отримати wsdl опис і через нього // Дотягнутися до самого веб-сервісу import java. net. URL; // такий ексепшн виникне під час роботи з об'єктом URL import java. net. MalformedURLEвідповідь; // класи, щоб пропарсувати xml-ку c wsdl описом // і дотягнутися до тега service в ньому import javax. xml. namespace. QName; import javax. xml. ws. Service; // інтерфейс нашого веб-сервісу (нам більше і потрібно) import uk. javarush. ws. HelloWebService; public class HelloWebServiceClient ( public static void main (String args) throws MalformedURLException ( // створюємо посилання на wsdl опис URL url = new URL ( "http://localhost:1986/wss/hello?wsdl") ; // Параметри наступного конструктора дивимося в першому тезі WSDL опису - definitions // Перший аргумент дивимося в атрибуті targetNamespace // Другий аргумент дивимося в атрибуті name QName qname = new QName ("http://ws.сайт/", "HelloWebServiceImplService"); // Тепер ми можемо дотягнутися до тега service у wsdl описі, Service service = Service. create (url, qname); // а далі і до вкладеного в нього тега port, щоб // отримати посилання на віддалений від нас об'єкт веб-сервісу HelloWebService hello=service. getPort (HelloWebService. class); // Ура! Тепер можна викликати віддалений метод System. out. println (hello. getHelloString ("JavaRush")); ) ) Максимум коментарів за кодом я дав у лістингу. Додати мені нічого, тому запускаємо (Shift+F10). Ми повинні у консолі побачити текст: Hello, JavaRush! Якщо не побачили, то мабуть забули запустити веб-сервіс.

Висновок

У цьому топіці був представлений короткий екскурс до веб-сервісів. Ще раз скажу, що багато з того, що я написав – це мої здогади щодо того, як це працює, і тому мені не варто довіряти. Буду вдячний, якщо знаючі люди мене виправлять, адже тоді я чогось навчуся. UPD.