Протокол SOAP. Протокол SOAP та Web Services

10 відповідей

WSDL - це документ XML, що описує веб-службу. Це фактично означає мову визначення веб-сервісів.

SOAP - це протокол на основі XML, який дозволяє обмінюватися інформацією за певним протоколом (наприклад, HTTP або SMTP) між програмами. Це означає простий протокол доступу до об'єктів і використовує XML для формату обміну повідомленнями для передачі інформації.

REST – це архітектурний стиль мережевих систем та виступає за передачу репрезентативного стану. Це не стандарт сам, але використовує такі стандарти як HTTP, URL, XML і т.д.

Щоразу, коли хтось згадує SOAP/WSDL, я думаю про об'єкти та класи, визначені в xml...

"Ви використовуєте SOAP так само, як і будь-який PHP-клас. Однак у цьому випадку клас не існує в локальній файловій системі додатків, а на віддаленому вузлі, доступ до якого здійснюється через http."... "Якщо ми думаємо використовувати SOAP- сервіс як ще один клас PHP, тоді документ WSDL є списком усіх доступних методів та властивостей класу.

І щоразу, коли хтось говорить про REST, я думаю про HTTP-команди (методи запиту), такі як POST, GET і DELETE

Приклад: простими словами, якщо ви маєте веб-сервіс калькулятора.

WSDL: WSDL розповідає про функції, які можна реалізувати або піддати дії клієнту. Наприклад: додавання, видалення, віднімання тощо.

SOAP: де, використовуючи SOAP, ви фактично виконуєте такі дії, як doDelete(), doSubtract(), doAdd(). Таким чином, SOAP та WSDL є яблуками та апельсинами. Ми не повинні їх порівнювати. Вони обидва мають власну функціональність.

Чому ми використовуємо SOAP та WSDL: для обміну незалежними даними на платформі.

РЕДАКТУВАТИ: У звичайному повсякденному житті:

WSDL:Коли ми йдемо до ресторану, ми бачимо пункти меню, це WSDL.

Проксі-класи:Тепер, після перегляду елементів меню, ми складаємо наш розум (обробляємо наш погляд на порядок): Отже, ми робимо в основному класи Proxy на основі документа WSDL.

SOAP:Потім, коли ми фактично замовляємо їжу на основі меню: мається на увазі, що ми використовуємо проксі-класи для виклику методів обслуговування, які виконуються за допомогою SOAP.:)

SOAP → SOAP (Простий прототип доступу до об'єктів) - це протокальний рівень програми, створений для взаємодії машини з машиною. Протокол визначає стандартні правила. Усі сторони, які використовують конкретний протокол, мають дотримуватись правил протоколу. Як і TCP, він розмотується транспортному рівні. Протокол SOAP розумітиметься на рівні програми (будь-яка програма, що підтримує SOAP - Axis2,.Net).

WSDL → SOAP-повідомлення складається з SoapEnevelope-> SoapHeader та SoapBody. Він не визначає, який формат повідомлень буде? які усі транспорти (HTTP, JMS) підтримуються? без цієї інформації. Для будь-якого клієнта, який хоче використовувати конкретний веб-сервіс для створення SOAP-повідомлень, важко. Навіть якщо вони це зроблять, вони не будуть впевнені, це працюватиме весь час. WSDL – це порятунок. WSDL (мова опису веб-служб) визначає операції, формати повідомлень та дані про транспортування для повідомлення SOAP.

REST → REST (передача стану вистави) заснована на транспорті. На відміну від SOAP, який орієнтований на дії, REST більше відноситься до ресурсів. REST знаходить ресурси за допомогою URL-адреси (приклад -http://(serverAddress)/employees/employeeNumber/12345) та залежить від транспортного протоколу (з HTTP-GET, POST, PUT, DELETE,...) для дій для виконання ресурсів. Служба REST знаходить ресурс на основі URL-адреси та виконує дію на основі дієслова дії транспорту. Це більше архітектурний стиль та умовності.

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

WSDL – це мова опису веб-сервісів. Запит, що закінчується на кінцевій точці ".wsdl", призведе до подання XML-повідомлення, що описує запит і відповідь, яка може очікувати використання. Він визначає договір між сервісом та клієнтом.

REST використовує HTTP для надсилання повідомлень до служб.

SOAP – специфікація, REST – це стиль.

Ви не збираєтеся "просто" розуміти щось складне.

WSDL - це мова, заснована на XML, для опису веб-служби. У ньому описуються повідомлення, операції та інформація про транспортну мережу, що використовуються службою. Ці веб-служби зазвичай використовують SOAP, але можуть використовувати інші протоколи.

WSDL читається програмою і тому може використовуватися для створення всього або частини коду клієнта, необхідного для виклику веб-служби. Це те, що означає виклик SOAP-орієнтованих веб-сервісів "самоописом".

REST взагалі не пов'язаний із WSDL.

Wikipedia говорить: "Мова опису веб-служб – це мова на основі XML, яка надає модель для опису веб-сервісів". Іншими словами, WSDL відноситься до веб-служби, оскільки javadoc відноситься до бібліотеки java.

Проте дуже приємна річ у WSDL у тому, що програмне забезпечення може генерувати клієнт і сервер, використовуючи WSDL.

Як уже говорилося в попередньому розділі, Web-служби обмінюються інформацією з клієнтами та між собою, посилаючи повідомлення мовою XML. Теги цієї реалізації XML, правила оформлення документа XML та порядок обміну документами визначено протоколом SOAP. Протокол SOAP створений у 1998 році командою розробників під керівництвом Дейва Вінера (Dave Winer), яка працювала в корпорації Microsoft та фірмі Userland. Назва протоколу – "Простий протокол доступу до об'єктів" – відображає його початкове призначення – звертатися до методів віддалених об'єктів. Призначення протоколу змінилося, тепер це протокол будь-якого взаємодії Web-служб і компонентів слабо пов'язаних розподілених додатків. Він уже не зовсім простий, та й про об'єкти він нічого не каже. Багато розробників пропонують назвати його "Service Oriented Architecture Protocol", залишивши колишнє скорочення. Щоб припинити ці спроби, у специфікації SOAP 1.2 зазначено, що слово "SOAP" відтепер не розшифровуватиметься.

Наприкінці 1999 року розробка протоколу було передано до консорціуму W3C (http:// www.w3.org/).

У травні 2000 року консорціум випустив свою версію SOAP 1.1. Послання, написане за протоколом SOAP, оформляється документом XML, який активно використовує простір імен. Імена елементів XML версії SOAP 1.1 належать до простору імен з ідентифікатором http://schemas.xmlsoap.org/soap/envelope/.

Чернетка другої версії SOAP 1.2 була випущена в 2001 році, її простір імен називався на той час http://www.w3.org/2001/06/soap-envelope.

Зауважте, що ідентифікатор простору імен, а не номер 1.1 або 1.2 визначає версію SOAP. Сервер не буде розглядати SOAP-послання і поверне повідомлення про помилку якщо помітить

невідповідність простору імен.

У той час, як я пишу ці рядки, версія SOAP 1.1 залишається робочою. Версія 1.2 ніяк не може вийти з підготовчої стадії, але вже використовується, наприклад, SOAP::Lite, Apache SOAP 2.3, Apache Axis. Тому в цьому розділі я викладатиму версію 1.2, відзначаючи її відмінності від версії 1.1.

Специфікація робочої версії SOAP завжди зберігається за адресою http://www.w3.org/TR/SOAP/. Документи, що лежать на цій адресі, замінюються новими при заміні робочої версії.

Чорна версія SOAP постійно оновлюється, змінюючи ідентифікатор простору імен. Найновіший варіант чорнової версії на час написання книги зберігався за адресою http://www.w3.org/TR/soapl2-partl/, а простір імен називався http://www.w3.org/2002/06/soap- envelope. Зауважте, що специфікація SOAP 12 і двох частин: part 1 і part2. Друга частина специфікації – додаток – містить правила запису складних типів даних. Специфікація має ще одну частину partO - приклади послань, складених за правилами SOAP 1.2.

Структура SOAP-послання

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

та інші атрибути, забезпечені префіксами. У кореневий елемент вкладається один необов'язковий елемент, який містить заголовок послання, і один обов'язковий елемент , який записується вміст послання. Версія 1.1 дозволяла після тіла записати довільні елементи, їх імена обов'язково слід було постачати префіксами. Версія 1.2 забороняє писати що-небудь після елемента . Коротше кажучи, загальна структура SOAP-послання така:

xmlns:env="http://www.w3.org/2002/06/soap-envelope">

< ! - Блоки заголовка ->

Елемент

, якщо він є у посланні, записується першим у тілі елемента . Крім атрибутів xmlns, в ньому може бути атрибут actor, що вказує адресою URI конкретний сервер SOAP, якому призначено послання.

Справа в тому, що SOAP-послання може пройти через кілька SOAP-серверів або через кілька програм на одному сервері. Ці програми виконують попередню обробку блоків заголовка послання та передають його один одному. Всі ці сервери та/або програми називаються SOAP-вузлами (SOAP nodes). Специфікація SOAP не визначає правила проходження послання ланцюжком серверів. Для цього розробляються інші протоколи, наприклад Microsoft WS-Routing.

Атрибут actor задає цільовий SOAP-вузол - той, який розташований в кінці ланцюжка і оброблятиме заголовок повністю. Значення

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

У версії 1.2 атрибут actor замінений на атрибут role, тому що в цій версії SOAP кожен вузол грає одну або кілька ролей. Специфікація поки що визначає три ролі SOAP-вузла.

Роль http://^^.w3.org/2002/06/soap-envelope/role/ultimateReceiver грає кінцевий, цільовий вузол, який оброблятиме заголовок.

Роль http://www.w3.org/2002/06/soap-envelope/role/next грає проміжний або цільовий вузол. Такий вузол може й інші, додаткові ролі.

Роль http://www.w3.org/2002/06/soap-envelope/role/none не повинен грати жоден SOAP-вузол.

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

Значенням атрибуту role може бути будь-який рядок URI, що показує роль вузла, якому призначений блок заголовка. Значенням за промовчанням для цього атрибуту є порожнє значення, тобто просто пара лапок, або рядок URI http://vw.v3.org/2002/06/soap-envelope/rale/ultimateReceiver.

Значення атрибута role показує, що блок повинен бути оброблений вузлом, що відіграє роль, визначену таким же рядком.

Ще один атрибут елемента

, званий urnstUnderstand, приймає значення або 1. Його значення за замовчуванням дорівнює о. Якщо атрибут mustunderstand дорівнює 1, то SOAP-вузол при обробці елемента обов'язково повинен враховувати його синтаксис, визначений у схемі документа, або зовсім не обробляти послання. Це збільшує точність обробки послання.

У версії SOAP 1.2 замість цифри треба писати слово false, а замість цифри 1 писати слово true.

В тіло заголовка

можна вкласти довільні елементи, які раніше називалися статтями (entries) заголовка. У версії 1.2 називаються блоками (blocks) заголовка. Їхні імена обов'язково позначаються префіксами. У блоках заголовка можуть зустрітися атрибути role або actor і mustunderstand. Їхня дія буде відноситися тільки до цього блоку. Це дозволяє обробляти окремі блоки заголовка проміжними SOAP-вузлами, тими, чия роль збігається з роллю, вказаною атрибутом role. У лістингу 3.1 наведено приклад такого блоку.

Лістинг 3.1. Заголовок з одним блоком

xmlns:t="http://some.com/transaction" env:role=

"http://www.w3.org/2002/06/soap-envelope/role/ultimateReceiver" env:mustUnderstand="1">

Елементи, вкладені у блоки заголовка, не називаються блоками. Вони не можуть містити атрибути role, actor і mustunderstand.

Елемент обов'язково записується відразу за елементом

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

Повідомлення про помилку

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

У повідомленні, записаному в тілі елемента версії SOAP 1.1

ються чотири частини, описані такими вкладеними елементами.

Код помилки - Повідомлення, яке показує тип помилки. Воно призначене для програми, яка обробляє помилки.

Опис помилки - словесний опис типу помилки, призначений для людини.

Місце виявлення помилки - адреса URI сервера, який помітив помилку. Корисно, коли послання проходить ланцюжок SOAP-вузлів для уточнення природи помилки. Проміжні SOAP-вузли обов'язково записують цей елемент, цільовий SOAP-сервер не повинен це робити.

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

Наприклад:

xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">

env:MustUnderstand SOAP Must Understand Error

Версія SOAP 1.2 змінила зміст елемента Як описано в

просторі імен http://www.w3.org/2002/06/soap-envelope, до нього входять два обов'язкові елементи і три необов'язкові елементи.

Обов'язкові елементи.

Код помилки . Він містить обов'язковий вкладений елемент<:value>з кодом помилки та необов'язковий вкладений елемент , що містить, знову-таки, елемент з уточнюючим кодом помилки та елемент і далі все повторюється рекурсивно.

Причина помилки . Містить необов'язковий атрибут xml: lang, що вказує мову повідомлення (див. Розділ Г), і довільна кількість вкладених елементів з описом помилки.

Необов'язкові елементи.

? - адреса URI проміжного SOAP-вузла, що помітив помилку.

? - роль SOAP-вузла, що помітив помилку.

? - Опис помилки, поміченої при обробці тіла послання, але з заголовка.

Лістинг 3.2 показує повідомлення про помилку, що виникла під час спроби виконання процедури. Помилка полягає в тому, що імена аргументів процедури неправильно записані в посланні SOAP і процедура не може їх зрозуміти.

Лістинг 3.2. Повідомлення про помилку

xmlns:env="http://www.w3.org/2002/06/soap-envelope" xmlns:rpc=’http://www.w3.org/2002/06/soap-rpc’>

env:Sender

rpc:BadArgumentsc/env:Value>

Ptocessing ETror

xmlns:e="http://www.example.org/faults"> №me does not match 999

Типи помилок

Список кодів помилок постійно змінюється та розширюється. Версія 1.1 визначає чотири типи помилок.

VersionMismatch - простір імен невідомий. Можливо, воно застаріло чи його ім'я написано неправильно.

MustUnderstand - блок заголовка, позначений атрибутом mustUnderstand зі значенням 1, не відповідає своєму синтаксису, визначеному у схемі документа.

Client - документ XML, що містить послання, неправильно сформований і тому сервер не може його обробити. Клієнту слід змінити послання.

Server - сервер не може обробити правильно записане послання через свої внутрішні причини.

Версія 1.2 визначає п'ять типів помилок.

VersionMismatch - простір імен невідомий. Можливо, воно застаріло або його назва написана неправильно, або в посланні зустрілося ім'я елемента XML, не визначене в цьому просторі імен. У заголовок відповіді сервер записує елемент , що перераховує вкладеними елементами правильні назви просторів імен, які розуміють сервер. Відповідь сервера показана у лістингу 3.3.

MustUnderstand - блок заголовка, позначений атрибутом mustunderstand зі значенням true, не відповідає своєму синтаксису, визначеному у схемі документа. Сервер записує у заголовок відповіді елементи , атрибут qname, який містить ім'я неправильного блоку. Лістинг 3.4 містить приклад відповіді, який буде зроблено сервером, якщо заголовок лістингу 3.1 виявиться неправильно записаним.

DataEncodingUnknown - у посланні зустрілися незрозумілі дані, можливо, вони записані в невідомому кодуванні.

Sender - документ XML, що містить послання, неправильно сформований і тому сервер не може його обробити. Клієнту слід змінити послання.

Receiver - сервер не може обробити правильно записане послання через свої внутрішні причини, наприклад, відсутній потрібний XML-парсер.

Сервер може додати до цих типів помилок якісь типи. Зазвичай

вони деталізують стандартні типи і повідомлення про них з'являються в елементах , як було показано вище у лістингу 3.2.

? Лістинг 3.3. Відповідь сервера з повідомленням про помилку типу VersionMismatch

xmlns:env="http://www.w3.org/2002/06/soap-envelope">

xmlns:upg="http://www.w3.org/2002/06/soap-upgrade">

xmlns:nsl="http://www.w3.org/2002/06/soap-envelope"/>

xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"/>

env:VersionMismatch

Version Mismatch

ЛістонгЗ.4. Відповідь сервера з повідомленням про помилку типу MustUnderstand

xmlns:t='http://some.com/transaction' />

env:MustUnderstand

One or more mandatory headers not understood

Література:

Хабібуллін І. Ш. Розробка Web-служб засобами Java. – СПб.: БХВ-Петербург, 2003. – 400 с: іл.

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

Вступ

Почати треба з того, навіщо створювалася концепція веб-сервісів. До моменту появи цього поняття у світі вже існували технології, що дозволяють програмам взаємодіяти на відстані, де одна програма могла викликати якийсь метод в іншій програмі, яка при цьому могла бути запущена на комп'ютері, розташованому в іншому місті чи навіть країні. Все це скорочено називається 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.

SOAP-текстовий протокол, який використовує XML для обміну структурованими повідомленнями у розподіленому обчислювальному середовищі. Спочатку SOAP призначався в основному для реалізації віддаленого виклику процедур (RPC), а назва була абревіатурою: Simple Object Access Protocol - простий протокол доступу до об'єктів. Наразі протокол використовується для обміну довільними повідомленнями у форматі XML, а не лише для виклику процедур. Офіційна специфікація останньої версії 1.2 протоколу не розшифровує назву SOAP. SOAP є розширенням протоколу XML-RPC. SOAP може використовуватися з будь-яким протоколом прикладного рівня: SMTP, FTP, HTTP та ін Однак його взаємодія з кожним з цих протоколів має свої особливості, які повинні бути визначені окремо. Найчастіше SOAP використовується поверх HTTP. SOAP є одним із стандартів, на яких базується технологія веб-сервісів. Зв'язок між веб-службами та їх клієнтами здійснюється за допомогою повідомлень у форматі XML. SOAP (Simple Object Access Protocol - простий протокол доступу до об'єктів) є протоколом повідомлень для вибору web-служб. Можна сказати, що формат SOAP ідеально підходить для технології RPC (Remote Procedure Call - виклик віддаленої процедури), так як SOAP-повідомлення містить параметри, що направляються клієнтом, або відсилається службою повертається величину.

Переваги застосування формату SOAP:

· Гнучкіші типи даних.

· Підтримка заголовків та розширень:

Недоліки:

· Використання SOAP для передачі повідомлень збільшує їх обсяг та знижує швидкість обробки. У системах, де швидкість важлива, частіше використовується пересилання документів XML через HTTP безпосередньо, де параметри запиту передаються як звичайні HTTP параметри.

· Хоча SOAP є стандартом, різні програми часто генерують повідомлення у несумісному форматі. Наприклад, запит згенерований AXIS-клієнтом не буде зрозумілий сервером WebLogic.

Основні концепції протоколу: Сторона, яка надсилає повідомлення SOAP, називається відправником SOAP, яка отримує – одержувачем SOAP. Шлях, який SOAP проходить від вихідного відправника до кінцевого одержувача називається маршрутом повідомлення. Маршрут повідомлення містить вихідного відправника, кінцевого одержувача та 0 або більше посередників SOAP. Об'єкти, які обробляють повідомлення згідно з правилами певних протоколів SOAP називаються SOAP-вузлами. Елементарна одиниця інформації, яка бере участь в обміні між вузлами SOAP, називається повідомленням SOAP – це документ XML з SOAP оболонкою кореневого елемента.

Brett McLaughlin Переклад Ілля Чекменєв

SOAP – це простий протокол доступу до об'єктів (Simple Object Access Protocol). Якщо ви ніколи раніше про нього не чули, то, мабуть, ви живете в якійсь глушині, далеко від цивілізації. Він став останнім писком моди у web програмуванні, та невід'ємною частиною web сервісів, які з таким фанатизмом використовуються у web розробках останнього покоління. Якщо ви чули про .NET, дітище Microsoft, або peer-to-peer "революції", то ви чули про технології, які ґрунтуються на використанні SOAP (навіть якщо ви не знаєте що це таке). Існує не одна, а двіреалізації SOAP, від Apache та від Microsoft, якій присвячені тисячі сторінок на їхньому сайті технічної підтримки MSDN (http://msdn.microsoft.com/).

У цій статті я розповім вам, що таке SOAP і чому він є такою важливою частиною в процесі розвитку парадигми web програмування. Це допоможе вам опустити фундаментальні основи і відразу розпочати роботу з інструментарієм SOAP. Потім я дам побіжний огляд існуючих проектів SOAP і заглиблююся в реалізацію від Apache. Ця стаття не претендує на відтворення повної картини SOAP, у моїй книзі "Java & XML, 2-а редакція" заповнено безліч прогалин. Відповіді на багато питань, що виникли після прочитання цієї статті, ви знайдете в книзі.

Вступ

Для початку потрібно розібратися в тому, що таке SOAP. Ви можете прочитати повний (і дуже довгий) висновок W3C за адресою http://www.w3.org/TR/SOAP. Потім, розібравшись і відкинувши все лушпиння, ви зрозумієте що SOAP це всього лише протокол. Це простий протокол (для його використання, немає необхідності в написанні нового), що ґрунтується на ідеї, що в певний момент у розподіленій архітектурі виникає необхідність обміну інформацією. Крім того, для систем, в яких існує ймовірність перевантажень і утруднень при обробці процесів, цей протокол дуже вигідний тим, що він легковажний і вимагає мінімальної кількості ресурсів. Нарешті, він дозволяє здійснювати всі операції через HTTP, що дозволяє обійти стороною такі хитрі штуки як firewall і вберегтися від прослуховування за допомогою сокетів неймовірного числа портів. Головне, щоб ви усвідомили це, а все інше – деталі.

Зрозуміло, ви хотіли б знати ці деталі, і я не омину їх увагою. У специфікації SOAP існує три базові компоненти: конверт SOAP (SOAP envelope), набір правил шифрування та засоби взаємодії між запитом та відповіддю. Давайте думати про повідомлення 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

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

Як ви бачите, шифрування задане всередині конверта, що дозволяє застосуванню визначити (використовуючи значення атрибута encodingStyle), чи зможе воно прочитати вхідне повідомлення, розташоване в елементі Body. Переконайтеся в правильності простору імен конверта SOAP, або сервери SOAP, які отримають ваше повідомлення, видадуть повідомлення про помилку через невідповідність версій, і ви не зможете взаємодіяти з ними.

Шифрування

Другий важливий елемент SOAP - це можливість шифрування типів даних користувача. У RPC (і XML-RPC) шифрування може виконуватися лише для заздалегідь визначених типів даних, які підтримуються в завантаженому XML-RPC інструментарії. Шифрування інших типів даних вимагає від вас самостійної модифікації сервера RPC і клієнта. З SOAP схема XML може бути досить легко використана для вказівки нових типів даних (за допомогою структури complexType, розглянутої у 2-му розділі моєї книги), і ці нові типи можуть бути представлені в XML як частина основного розділу SOAP. Завдяки інтеграції зі схемою XML, ви можете шифрувати будь-який тип даних у SOAP повідомленні, логічно описавши його у схемі XML.

Виклик

Найкращий спосіб зрозуміти, як працює виклик 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 boughtTickets = (Boolean)client.execute("ticketCounter.buyTickets", params); // Обробка відповіді

Я створив найпростішу програму для замовлення авіаквитків. Тепер погляньте на Приклад 12-3 , який показує виклик у SOAP.

Приклад 12-3. Виклик у SOAP

// Створення параметрів Vector params = New Vector(); params.addElement(new Parameter("flightNumber", Integer.class, flightNumber, null)); params.addElement(new Parameter("numSeats", Integer.class, numSeats, null)); params.addElement(new Parameter("creditCardType", String.class, creditCardType, null)); params.addElement(new Parameter("creditCardNumber", Long.class, creditCardNum, null)); // Створення об'єкта Call Call call = new Call(); call.setTargetObjectURI("urn:xmltoday-airline-tickets"); call.setMethodName("buyTickets"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); call.setParams(params); // Виклик Response res = call.invoke(new URL("http://rpc.middleearth.com"), ""); // Обробка відповіді

Як ви бачите, що виклик, представлений об'єктом Call, резидентний у пам'яті. Він дозволяє вам задати мету виклику, метод виклику, стиль шифрування, параметри, і багато інших параметрів, які не представлені в цьому прикладі. Це більш гнучкий механізм, ніж метод XML-RPC, що дозволяє явно задавати набір різних параметрів, які опосередковано визначаються в XML-RPC. Далі в цій статті ви дізнаєтеся більше про процес виклику, у тому числі ви дізнаєтеся як SOAP обробляє невірні запити, ієрархію помилок і, зрозуміло, результати виклику, що повертаються.

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

Налаштування

Тепер, коли ви познайомилися з основами концепції, настав час найцікавішої частини: програмування. Для цього вам знадобиться зручний проект або продукт, знайти який простіше, ніж може здатися на перший погляд. Якщо вам потрібний Java проект, що надає можливості SOAP, його не треба довго шукати. Існує дві групи продуктів: комерційні та безкоштовні. Як і у своїй книзі, я уникатиму згадки комерційних продуктів. Це зовсім не тому, що вони погані (навіть навпаки, деякі з них прекрасні), а тому, що я хотів би, щоб будь-який читач міг спробувати будь-який із наведених прикладів. Це з доступністю, якої багато комерційних продуктів не мають. Ви повинні заплатити за їх використання, або тимчасово використовувати їх протягом обмеженого періоду часу після завантаження.

Таким чином, ми плавно підійшли до проектів з відкритим джерелом (open source). З цієї галузі я можу назвати лише один продукт: Apache SOAP. Він розташований за адресою http://xml.apache.org/soap та надає інструментарій SOAP для Java. На момент написання книги вийшла версія 2.2, яку ви можете завантажити з веб-сайту Apache. Саме цю версію я і використовуватиму в прикладах цієї статті.

Інші альтернативи

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

Як щодо IBM SOAP4J?

Першим у списку альтернатив є реалізація від IBM: SOAP4J. Робота IBM лягла в основу проекту Apache SOAP, як і IBM XML4J переросла в те, що тепер відомо як проект XML парсера Apache Xerces. Передбачається, що реалізація від IBM буде перероблена, об'єднавшись з Apache SOAP. Приблизно те ж трапилося з IBMовським XML4J: тепер він лише забезпечує пакетування в Xerces. Це тільки підкреслює тенденції - великі виробники часто підтримують і використовують OpenSource проекти, в даному випадку обидва проекти (Apache і IBM) використовують одну і ту ж кодову базу .

Хіба Microsoft поза грою?

Зрозуміло, ні. Microsoft і його реалізація SOAP, так само як і весь напрямок.NET (докладніше розглянутий у моїй книзі), дуже значні. Насправді я хотів приділити більшу частину часу детальному розгляду реалізації SOAP від ​​Microsoft, але вона підтримує тільки COM об'єкти з ними і не підтримує Java. З огляду на ці причини подібний опис не міг увійти до статті про Java та XML. Тим не менш, Microsoft (незважаючи на всі претензії, які ми, як розробники, маємо до цієї компанії) проробила важливу роботу у сфері web сервісів, і ви зробите помилку якщо без роздумів її відкинете, керуючись лише голими емоціями. Якщо у вас є необхідність працювати з COM або компонентами Visual Basic, я настійно рекомендую спробувати використовувати інструментарій Microsoft SOAP, доступний за адресою 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 у бінарному форматі (з підкаталогу version-2.2). Потім ви повинні розархівувати вміст архіву в директорію на вашому комп'ютері. У моєму випадку це була директорія javaxml2 (c:\javaxml2на моєму комп'ютері з Windows, /javaxml2на моєму комп'ютері з Mac OS X). В результаті файли розархівувалися в /javaxml2/soap-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 файли у вашу classpath, а також бібліотеку soap.jar. Кожен з цих jar файлів повинен бути або в кореневому каталозі відповідної програми, або в підкаталозі /lib. Після завершення ваша змінна classpathмає виглядати приблизно так:

$ 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/soap-2_2/у ваш classpathдля запуску прикладів SOAP. Я описав налаштування для кількох прикладів, наведених у цьому розділі.

Сервер

Щоб створити SOAP-сумісний набір серверних компонентів вам для початку знадобиться двигун сервлета. Як і в попередніх розділах, як приклад для цього розділу я використовував Apache Tomcat (доступний на http://jakarta.apache.org/). Вам потрібно додати все необхідне клієнту в classpathсервера. Найпростіший спосіб зробити це – скинути soap.jar, 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 c Tomcat, вам потрібно буде повторити фокус, який я описував у розділі 10. Перейменуйте parser.jarв z_parser.jar, а jaxp.jarв z_jaxp.jar, щоб переконатися, що xerces.jarта увімкнена версія JAXP завантажується перед будь-яким іншим парсером або реалізацією JAXP.

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

Сервлет маршрутизатора та клієнт адміністратора

Крім основних операцій, Apache SOAP включає сервлети маршрутизатора, а також клієнт адміністратора. Навіть якщо ви не збираєтеся використовувати їх, я рекомендую вам встановити їх, щоб протестувати правильність установки SOAP. Цей процес залежить від того, який двигун сервлетів ви використовуєте, тому я обмежуся описом процесу встановлення для Tomcat. Інструкції з встановлення для деяких інших движків сервлетів ви знайдете на http://xml.apache.org/soap/docs/index.html.

Установка під Tomcat дуже проста: просто візьміть файл soap.warз директорії soap-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 list Deployed Services:

Ви повинні отримати порожній список сервісів, як показано вище. Якщо ви отримаєте будь-які повідомлення, ознайомтеся з довгим переліком можливих помилок, доступним на http://xml.apache.org/soap/docs/trouble/index.html. Це найбільш повний список проблем, з якими ви могли зіткнутися. Якщо ви отримали порожній список, це означає, що налаштування завершено, і ви готові почати розгляд прикладів, наведених у цьому розділі.

Приступимо

Існує три основні етапи написання будь-яких систем на базі SOAP. Перерахувавши, я коротко зупинюся на кожній із них:

  • Вибір між SOAP-RPC та SOAP повідомленнями;
  • Написання чи отримання доступу до SOAP сервісу;
  • Написання чи отримання доступу до SOAP клієнта.

Першим етапом є вибір, чи будете використовувати SOAP для RPC викликів (при яких віддалена процедура виконується на сервері), або повідомлення (коли клієнт просто посилає фрагменти інформації серверу). Я докладно розглядаю ці процеси. Після того як ви прийняли це рішення, вам знадобиться отримати доступ або створити власний сервіс. Зрозуміло, оскільки всі ми - професіонали в Java, у цьому розділі розповідається про те, як створити свій власний. І, нарешті, вам потрібно написати клієнта для цього сервісу, от і всі справи!

RPC чи Messaging?

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

Інший стиль роботи SOAP базується на обміні повідомленнями. Замість виконання віддалених процедур він використовується тільки для обміну інформацією. Як ви можете здогадатися, це потужний інструмент, який не вимагає знання клієнтом окремих методів сервера. Він також робить моделювання віддалених систем більш ізольованим, дозволяючи використовувати пакети даних (пакети у фігуральному значенні, а не мережному) для передачі іншим системам. При цьому іншим системам не обов'язково знати про операції, які відбувалися з цими даними. Такий стиль складніше ніж RPC програмування, тому я не буду ривати його тут. Ви знайдете його у моїй книзі, поряд з іншими деталями бізнес-бізнес взаємодії. А для початку познайомтеся із SOAP-RPC програмуванням.

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

RPC сервіс

Тепер, коли з формальностями покінчено, настав час діяти. Як ви знаєте, в RPC вам знадобляться класи, методи яких виконуватимуться віддалено.

Фрагменти коду

Я почну з розгляду фрагментів коду для сервера. Ці фрагменти є класи з методами, що виконуються для RPC клієнтів. Як приклади я використав код зі своєї книги. Замість того, щоб використовувати прості класи, я вибрав більш складний приклад, щоб якомога наочніше продемонструвати можливості SOAP. Отже, як приклад я використав клас CD. Спочатку визначаємо елемент mapкожного нестандартного типу параметрів. Для атрибуту encodingStyleпринаймні в Apache SOAP 2.2. ви повинні вказати значення http://schemas.xmlsoap.org/soap/encoding/. На даний момент це єдине кодування, що підтримується. Вам потрібно вказати простір імен типу, що визначається користувачем, а потім ім'я класу з префіксом простору імен для цього типу. У нашому випадку для цих цілей я використав вигаданий простір імен та простий префікс. x". Потім, використовуючи атрибут javaType, задав реальне ім'я Java класу (для цього випадку - javaxml2.CD). І, нарешті, куралесил з атрибутами java2XMLClassNameі xml2JavaClassName. З їхньою допомогою задається клас, конвертований з Java в XML і навпаки. Я використав чудовий клас BeanSerializer, що також входить до комплекту поставки Apache SOAP. Якщо ваш параметр користувача у форматі JavaBean, цей серіалізатор і десеріалізатор позбавить вас необхідності писати свій власний. Вам потрібен клас із конструктором за умовчанням (згадайте, для класу CD я поставив простий, без будь-яких параметрів конструктор), і публікація всіх даних цього класу за допомогою методів setXXXі getXXX. Оскільки клас CDчудово задовольняє всім цим вимогам, BeanSerializerпрацює ідеально.

Примітка:Те, що клас CDвідповідає вимогам BeanSerializer. немає великого значення. Більшість класів легко наводяться до цього формату. Тому я раджу уникати написання власних серіалізаторів та десеріалізаторів. Це зайвий головний біль (нічого складного, але занадто ретельно) і рекомендую вам заощадити сили і використовувати в своїх параметрах конвертацію бінів. У багатьох випадках перетворення бінів вимагають лише наявності у класі конструктора за умовчанням (без параметрів).

Тепер повторно відтворимо jarфайл і перерозмістимо наш сервіс:

(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

package javaxml2; import java.net.URL; import java.util.Vector; import org.apache.soap.Constants; import org.apache.soap.Fault; import org.apache.soap.SOAPException; import org.apache.soap.encoding.SOAPMappingRegistry; import org.apache.soap.encoding.soapenc.BeanSerializer; import org.apache.soap.rpc.Call; import org.apache.soap.rpc.Parameter; import org.apache.soap.rpc.Response; import org.apache.soap.util.xml.QName; Public class CDAdder ( public void add(URL url, String title, String artist, String label) throws SOAPException ( System.out.println("Додавання CD з назвою "" + title + "" виконавця "" + artist + "" студії " + label); CD cd = New CD (title, artist, label); // Створення об'єкта виклику Call Call call = new Call(); call.setSOAPMappingRegistry(registry); call.setTargetObjectURI("urn:cd-catalog"); call.setMethodName("addCD"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); // Встановлення параметрів Vector params = new Vector(); params.addElement(new Parameter("cd", CD.class, cd, null)); call.setParams(params); // Обробка Invoke виклику Response response; 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("Шаблон: java javaxml2.CDAdder " + "\"[Заголовок CD]\" \"[Ім'я виконавця]\) "\"[Студія CD]\""); return; try ( // URL SOAP сервера, якого здійснюється підключення URL url = new URL(args); // Get values ​​for new CD String title = args; String artist = args; String label = args; //Add CD CDAdder adder = new CDAdder(); adder.add(url, title, artist, label); ) catch (Exception e) ( e.printStackTrace(); ) ) )

Єдина по-справжньому цікава зміна пов'язана з відображенням класу CD:

// Відображення цього типу, щоб його можна було використовувати із SOAP SOAPMappingRegistry registry = new SOAPMappingRegistry(); BeanSerializer serializer = новий BeanSerializer(); registry.mapTypes(Constants.NS_URI_SOAP_ENC, новий QName("urn:cd-catalog-demo", "cd"), CD.class, serializer, serializer);

Ось яким чином параметр користувача може бути кодований і переданий по мережі. Я вже розповідав яким чином клас BeanSerializerможе бути використаний для обробки параметрів у форматі JavaBean, наприклад, таких як клас CD. Для вказівки сервера я використовував дискриптор розміщення, незважаючи на це тепер мені потрібно повідомити клієнта, що потрібно використовувати цей серіалізатор і десеріалізатор. Цю функцію і виконує клас SOAPMappingRegistry. Метод mapTypes()бере зашифрований рядок (і знову для цього краще використовувати константу NS_URI_SOAP_ENC), та інформацію про тип параметра, для якого має використовуватись спеціальна серіалізація. Спочатку вказується QName. Ось чому в дискрипторі розміщення було використано дивне місце імен. Вам потрібно вказати тут той самий URN, а також локальне ім'я елемента (для цього прикладу "CD"), потім Java об'єкт Classкласу, який буде серіалізовано ( CD.class) і, нарешті, екземпляр класу для серіалізації та десеріалізації. Для цього прикладу в обох випадках фігуруватиме екземпляр BeanSerializer. Після того, як усі ці налаштування будуть внесені до реєстру, повідомте про це об'єкт Callза допомогою методу setSOAPMapping-Registry().

Ви можете запустити цей клас, як було показано раніше, додавши CD, і все має працювати як належить:

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

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

Примітка: Ви можете вирішити що, оскільки клас CDListerбезпосередньо не взаємодіє з об'єктом CD(повертається методом list()значення має тип Hashtable), то вам не потрібно вносити будь-яких змін. Тим не менш, клас, що повертається Hashtableмістить екземпляри об'єкта CD. Якщо SOAP не знає, як їх десеріалізувати, клієнт видасть повідомлення про помилку. У цьому випадку для вирішення проблеми ви повинні вказати в об'єкті Callекземпляр SOAPMappingRegistry.

Ефективне оброблення помилок

Тепер, коли ви познайомилися з об'єктами користувача, зробили RPC виклики та інше, дозвольте мені розповісти про менш захоплюючу тему: обробці помилок. При будь-якій мережній транзакції може статися багато збоїв. Не запускається сервіс, помилка в роботі сервера, не вдається знайти об'єкт, відсутні класи та багато інших проблем. Досі я просто використав метод fault.getString()для створення повідомлень про помилки. Але цей метод не завжди може бути корисним. Щоб побачити його в дії, зніміть коментар у конструкторі CDCatalog:

public CDCatalog() ( //catalog = New Hashtable(); // Створення каталогу addCD(new CD("Nickel Creek", "Nickel Creek", "Sugar Hill")); addCD(new CD("Let it Fall", "Sean Watkins", "Sugar Hill")); addCD(new CD("Aerial Boundaries", "Michael Hedges", "Windham Hill")); addCD(new CD("Taproot", "Michael Hedges", "Windham Hill")); )

Перекомпілюйте його, перезапустіть двигун сервлета і перемістіть його. Внаслідок цього виникне виняткова ситуація NullPointerExceptionпри спробі конструктора класу додати CD в неініціалізований Hashtable. При запуску клієнта з'явиться повідомлення про помилку, але воно буде дуже інформативним:

(gandalf)/javaxml2/build$ java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcrouter Перегляд поточного каталогу CD. Помилка: Не вдається розв'язати цільовий об'єкт: null

Це зовсім не та інформація, яка може допомогти при виявленні та виправленні помилки. Тим не менш, фреймуорк справно справляється з обробкою помилок. Ви пам'ятайте DOMFaultListener, який ви ставили як значення елемента faultListener? Настала його година вступити в гру. Об'єкт, що повертається у разі помилки Faultмістить DOM (об'єктну модель документа) org.w3c.dom.Elementз детальною інформацією про помилку. Спочатку додайте у вихідний код вираз для імпортування java.util.Iterator:

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

Тепер внесемо зміни для обробки помилок у методі list():

if (!response.generatedFault()) ( Parameter returnValue = response.getReturnValue(); Hashtable catalog = (Hashtable)returnValue.getValue(); Enumeration e = catalog.keys(); title = (String)e.nextElement(); CD cd = (CD)catalog.get(title); + " студії " + cd.getLabel()); ) ) else ( Fault fault = response.getFault(); System.out.println("Помилка: " + fault.getFaultString()); Vector entries = 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 Element, що міститься у кожному запису. По суті, XML з яким ви працюєте:

SOAP-ENV:Server.BadTargetObjectURI Неможливо вирішити цільовий об'єкт: null Ось те, чого хочемо!

Іншими словами, об'єкт Fault надає вам доступ до частини конверта SOAP, яка містить помилки. Крім того, Apache SOAP забезпечує трасування стека Java у разі виникнення помилок, що надає деталізовану інформацію, необхідну для їх виправлення. Перехопивши елемент stackTraceі роздрукувавши значення вузла Textз цього елемента ваш клієнт може роздрукувати трасування стека сервера. Скомпілювавши ці зміни та перезапустивши клієнт ви отримаєте наступний результат:

C:\javaxml2\build>java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcr outer Перегляд поточного каталогу CD. Помилка: Неможливо вирішити цільовий об'єкт: 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 не передбачає цього, але подібні можливості можуть бути додані в майбутньому. Тому не дивуйтеся, якщо зустрінетеся з активними обговореннями цієї теми.