Статьи

Web-сервіси Java: Освоєння і моделювання WSDL 1.1

  1. Серія контенту:
  2. Цей контент є частиною серії: Web-сервіси Java
  3. Про це циклі статей
  4. Розбір WSDL 1.1
  5. компоненти опису
  6. Лістинг 1. BookServerInterface.wsdl
  7. Лістинг 2. BookServerImpl.wsdl
  8. деталі компонентів
  9. Малюнок 1. Зв'язки між компонентами WSDL
  10. Порівняння SOAP 1.1 і 1.2
  11. Робота з WSDL
  12. модель WSDL
  13. Лістинг 3. Клас Definitions (частково)
  14. інші доповнення
  15. Ресурси для скачування

Web-сервіси Java

Як WSDL 1.1 визначає Web-сервіси, і як створити моделі на мові Java для верифікації і перетворення WSDL-документів

Серія контенту:

Цей контент є частиною # з серії # статей: Web-сервіси Java

https://www.ibm.com/developerworks/ru/views/global/libraryview.jsp?series_title_by=web-сервисы+java

Слідкуйте за виходом нових статей цієї серії.

Цей контент є частиною серії: Web-сервіси Java

Слідкуйте за виходом нових статей цієї серії.

Про це циклі статей

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

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

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

У цій статті ми покажемо, як розібрати документи WSDL 1.1, і розглянемо перші частини моделі Java для перевірки WSDL-документів і їх перетворення в стандартну форму.

Розбір WSDL 1.1

Використовувані простору імен

У цій статті використовуються:

  • префікс wsdl для подання простору імен WSDL 1.1 http://schemas.xmlsoap.org/wsdl/;
  • префікс soap для простору імен http://schemas.xmlsoap.org/wsdl/soap/, використовуваного розширенням SOAP 1.1 для WSDL 1.1;
  • префікс xs для простору імен http://www.w3.org/2001/XMLSchema, використовуваного для визначень XML-схеми.

Редакція 1.1 WSDL, опублікована на початку 2001 року, технічно замінена рекомендаціями W3C WSDL 2.0, опублікованими в 2007 році. WSDL 2.0 пропонує більш чітку структуру, ніж WSDL 1.1, поряд з більшою гнучкістю. Але WSDL 2.0 страждає від проблеми курки і яйця: WSDL 2.0 не використовується широко, бо не підтримується широко, а так як він широко не використовується, у розробників стеків Web-сервісів мало стимулів його підтримувати. Незважаючи на всі його недоліки, для більшості цілей WSDL 1.1 досить хороший.

Оригінальна специфікація WSDL 1.1 була неточною щодо кількості використовуваних функцій. Так як в центрі уваги WSDL була робота з визначеннями служб SOAP, він включав також підтримку функцій SOAP (таких як кодування rpc), які пізніше виявилися небажаними. Організація Web Services Interoperability Organization (WS-I) вирішила ці проблеми в Базовому профілі (BP), який містить практичні рекомендації по Web-сервісів з використанням SOAP і WSDL. BP 1.0 був затверджений в 2004 році, а в 2006 році вийшла редакція BP 1.1. У цій статті розглядається WSDL 1.1 на базі рекомендацій BP WS-I і не будуть зачіпатися фактично застарілі функції, такі як кодування rpc для SOAP.

Передбачається, що структура XML-документів задається визначеннями XML-схеми. У первісну специфікацію WSDL 1.1 входить опис схеми, але ця схема в декількох аспектах не відповідає текстовим описам. Пізніше це було виправлено в модифікованої версії схеми, але документ WSDL 1.1 ні відредагований з урахуванням цієї зміни. Потім група BP WS-I вирішила внести ще більше змін в схему WSDL і створила те, що підноситься як практичні рекомендації до цієї слизької схемою. Документи, написані для однієї версії схеми, як правило, не сумісні з іншими версіями (незважаючи на те, що використовується один і той же простір імен), але на щастя, більшість інструментів Web-сервісів в основному ігнорує схему і приймає все, що виглядає розумним. (Див. Посилання на багато схеми WSDL в розділі ресурси ).

Навіть версія BP WS-I схеми WSDL 1.1 не надто допомагає гарантувати відповідність специфікації документів WSDL 1.1. Схема не відображає всіх обмежень BP WS-I, особливо щодо порядку проходження компонентів. Крім того, XML-схема не здатна обробити багато типів легко встановлюваних обмежень в документах (такі як альтернативні атрибути або необхідні додаткові елементи з окремою схеми). Тому перевірка відповідності документа WSDL 1.1 специфікації WSDL 1.1 (з поправками, внесеними BP WS-I) включає в себе набагато більше, ніж просто виконання валідації XML-схеми. Ми ще повернемося до цієї теми в цій статті. Але спочатку розглянемо структуру описів сервісу WSDL 1.1.

компоненти опису

У документах WSDL 1.1 використовується фіксований кореневий елемент зі зручним назвою <wsdl: definitions>. В межах цього кореневого елемента в просторі імен WSDL 1.1 визначено один «пасивний» дочірній елемент (просто посилання на окремі документи WSDL 1.1) і п'ять «активних» дочірніх елементів (які власне і складають опис сервісу):

  • <Wsdl: import> посилається на окремий документ WSDL 1.1 з описами, що підлягають включенню в цей документ;
  • <Wsdl: types> визначає типи XML або елементи, які використовуються для обміну повідомленнями;
  • <Wsdl: message> визначає фактичне повідомлення з точки зору типів або елементів XML;
  • <Wsdl: portType> визначає абстрактний набір операцій, здійснених сервісом;
  • <Wsdl: binding> визначає фактичну реалізацію <wsdl: portType> за допомогою конкретних протоколів і форматів;
  • <Wsdl: service> визначає сервіс в цілому, як правило, включає один або кілька елементів <wsdl: port> з інформацією доступу для елементів <wsdl: binding>.

Існує також елемент <wsdl: document>, який може використовуватися для цілей документування, як перший дочірній елемент <wsdl: definitions>, а також перший дочірній елемент будь-якого з вищевказаних елементів.

Для повного опису сервісу, як правило, потрібно, принаймні, один елемент кожного з цих типів, за винятком <wsdl: import>, але не обов'язково, щоб всі вони перебували в одному і тому ж документі. Для складання повного опису WSDL з декількох документів можна використовувати <wsdl: import>, що дозволяє поділяти опису для потреб організації. Наприклад, перші три елементи опису (<wsdl: types>, <wsdl: message "і" wsdl: portType>) разом складають повний опис інтерфейсу сервісу (можливо, певного групою архітектури), так що їх має сенс тримати окремо від орієнтованих на реалізацію елементів <wsdl: binding "і" wsdl: service>. Всі великі стеки Web-сервісів підтримують поділ описів на кілька WSDL-документів.

У лістингах 1 і 2 показаний приклад опису сервісу WSDL, розбитого на два WSDL-документа, так що компоненти опису інтерфейсу міститься в файлі BookServerInterface.wsdl, а компоненти реалізації - в файлі BookServerImpl.wsdl. У лістингу 1 показаний BookServerInterface.wsdl.

Лістинг 1. BookServerInterface.wsdl
<Wsdl: definitions ... xmlns: tns = "http://sosnoski.com/ws/library/BookServerInterface" targetNamespace = "http://sosnoski.com/ws/library/BookServerInterface"> <wsdl: document> Book service interface definition. </ wsdl: document> <wsdl: types> <xs: schema ... targetNamespace = "http://sosnoski.com/ws/library/BookServerInterface"> <xs: import namespace = "http: / /sosnoski.com/ws/library/types "schemaLocation =" book-types.xsd "/> ... </ xs: schema> </ wsdl: types> <wsdl: message name =" getBookMessage "> <wsdl: part name = "part" element = "tns: getBook" /> </ wsdl: message> <wsdl: message name = "getBookResponseMessage"> <wsdl: part name = "part" element = "tns: getBookResponse" /> < / wsdl: message> ... <wsdl: message name = "addBookMessage"> <wsdl: part name = "part" element = "tns: addBook" /> </ wsdl: message> <wsdl: message name = "addBookResponseMessage "> <wsdl: part name =" part "element =" tns: addBookResponse "/> </ wsdl: message> <wsdl: message name =" addDuplicateFault "> <wsdl: part name =" fault "element =" tns: addDuplicate "/> </ wsdl: message> <wsdl: portT ype name = "BookServerPortType"> <wsdl: documentation> Book service implementation. This creates an initial library of books when the class is loaded, then supports method calls to access the library information (including adding new books). </ Wsdl: documentation> <wsdl: operation name = "getBook"> <wsdl: documentation> Get the book with a particular ISBN. </ Wsdl: documentation> <wsdl: input message = "tns: getBookMessage" /> <wsdl: output message = "tns: getBookResponseMessage" /> </ wsdl: operation> ... <wsdl: operation name = "addBook" > <wsdl: documentation> Add a new book. </ wsdl: documentation> <wsdl: input message = "tns: addBookMessage" /> <wsdl: output message = "tns: addBookResponseMessage" /> <wsdl: fault message = " tns: addDuplicateFault "name =" addDuplicateFault "/> </ wsdl: operation> </ wsdl: portType> </ wsdl: definitions>

У лістингу 2 показаний BookServerImpl.wsdl. Елемент <wsdl: import> на початку імпортує опис інтерфейсу BookServerInterface.wsdl.

Лістинг 2. BookServerImpl.wsdl
<Wsdl: definitions ... xmlns: ins = "http://sosnoski.com/ws/library/BookServerInterface" xmlns: tns = "http://sosnoski.com/ws/library/BookServer" targetNamespace = "http: //sosnoski.com/ws/library/BookServer "> <wsdl: document> Definition of actual book service implementation. </ Wsdl: document> <wsdl: import namespace = "http://sosnoski.com/ws/library/BookServerInterface" location = "BookServerInterface.wsdl" /> <wsdl: binding name = "BookServerBinding" type = "ins: BookServerPortType "> <soap: binding transport =" http://schemas.xmlsoap.org/soap/http "style =" document "/> <wsdl: operation name =" getBook "> <soap: operation soapAction =" urn: getBook "/> <wsdl: input> <soap: body /> </ wsdl: input> <wsdl: output> <soap: body /> </ wsdl: output> </ wsdl: operation> ... <wsdl: operation name = "addBook"> <soap: operation soapAction = "urn: addBook" /> <wsdl: input> <soap: body /> </ wsdl: input> <wsdl: output> <soap: body /> </ wsdl: output> <wsdl: fault name = "addDuplicateFault"> <soap: fault name = "addDuplicateFault" /> </ wsdl: fault> </ wsdl: operation> </ wsdl: binding> <wsdl: service name = " BookServer "> <wsdl: port name =" BookServerPort "binding =" tns: BookServerBinding "> <soap: address location =" http: // localhost: 8080 / cxf / BookServer "/> </ wsdl: port> </ wsdl : service> </ wsdl: definitions>

Крім визначень елементів (і атрибутів) в просторі імен WSDL 1.1, WSDL 1.1 визначає також додаткові елементи. Вони призначені для заповнення конкретних осередків в описах сервісів WSDL 1.1 для передачі додаткової інформації, необхідної для конкретного типу сервісів. Єдині додаткові елементи WSDL 1.1, які все ще широко використовуються, це прив'язки для SOAP 1.1 (вони представлені в в лістингу 2 , В елементах <wsdl: binding "і" wsdl: service>), які були визначені в первісної специфікації WSDL 1.1, і для SOAP 1.2, певні окремої специфікації в 2006 році.

деталі компонентів

Елемент <wsdl: types> містить всі визначення XML, які використовуються для повідомлень, у вигляді одного або декількох елементів <xs: schema>. (WSDL допускає альтернативи XML-схемі для цих визначень, але більшість стеків підтримує тільки XML-схеми). Якщо потрібно, елементи <xs: schema> можуть використовувати <xs: import> або <xs: include> для включення інших схем, зовнішніх по відношенню до WSDL (а також посилатися на окремі схеми всередині одного і того ж WSDL).

Оскільки один елемент <wsdl: types> може містити будь-яку кількість визначень схеми, немає ніяких причин використовувати в документі WSDL більше одного елемента <wsdl: types>. В лістингу 1 елемент <wsdl: types> знаходиться у верхній частині BookServerInterface.wsdl.

Крім <wsdl: import> і <wsdl: types>, всіма компонентами верхнього рівня документа WSDL присвоєні окремі імена з використанням обов'язкового атрибута name. При використанні атрибуту targetNamespace в кореневому елементі <wsdl: definitions> документа (що зазвичай найкраще), імена цих компонентів визначено в цьому цільовому просторі імен. Це означає, що при визначенні імені досить привласнити просту, або «локальну», частина імені, але посилання на цей компонент повинні уточнювати ім'я за допомогою префікса простору імен або за допомогою простору імен за замовчуванням. На малюнку 1 показані найбільш важливі зв'язки між компонентами WSDL, причому суцільні лінії відповідають посиланнях по повному імені, а пунктирні - по імені, яке використовується для ідентифікації без уточнення простору імен.

Малюнок 1. Зв'язки між компонентами WSDL

Повідомлення, подані елементами <wsdl: message>, розташовані в ядрі описів сервісів WSDL. Елементи <wsdl: message> - це опису XML-даних, переданих між клієнтом і постачальником послуг. Кожен елемент <wsdl: message> містить нуль або більше (зазвичай один) дочірніх елементів <wsdl: part>. Для кожного елемента part потрібно власний атрибут name (унікальний в межах <wsdl: message>) і один з атрибутів element або type, який посилається на визначення схеми XML-даних. Кілька елементів <wsdl: message> показані в лістингу 1 , Після елемента <wsdl: types> в BookServerInterface.wsdl.

Елементи <wsdl: portType> визначають абстрактний інтерфейс сервісу в частині повідомлень, переданих сервісу та прийнятих від нього. Елементи <wsdl: portType> містять будь-яку кількість дочірніх елементів <wsdl: operation>. Кожному дочірньому елементу <wsdl: operation> потрібно власний атрибут name (BP WS-I вимагає, щоб він був унікальним в межах <wsdl: portType>), і в ньому міститься один або кілька дочірніх елементів, що описують повідомлення, що використовуються операцією. Дочірні елементи бувають трьох типів, що відповідають різним способам використання:

  • <Wsdl: input>: дані, що відправляються клієнтом постачальнику послуг в якості вхідних даних для операції;
  • <Wsdl: output>: дані, які повертаються клієнту постачальником послуг як результат операції;
  • <Wsdl: fault>: дані, які повертаються клієнту постачальником послуг при виникненні помилки в процесі обробки.

WSDL 1.1 визначає кілька шаблонів взаємодії між клієнтом і постачальником послуг, представлених різними послідовностями дочірніх елементів <wsdl: input> і <wsdl: output>, але не всі моделі досить добре визначені, щоб їх можна було реалізувати. BP WS-I допускає лише дві моделі: операцій типу запит-відповідь, де за <wsdl: input> слід <wsdl: output>, і односторонні операції, що містять тільки <wsdl: input>. У разі операцій типу запит-відповідь (на сьогоднішній день найбільш поширений тип) за елементами <wsdl: input> і <wsdl: output> може слідувати будь-яку кількість елементів <wsdl: fault>.

Кожен елемент <wsdl: input>, <wsdl: output> або <wsdl: fault> посилається на опис повідомлення за допомогою обов'язкового атрибута message. Це посилання з уточненням простору імен, тому вона зазвичай вимагає додавання префікса. Приклади можна побачити в лістингу 1 : Наприклад, коли елемент <wsdl: input message = "tns: getBookMessage" /> використовується в описі операції getBook. (Префікс tns служить визначенням кореневого елемента <wsdl: definitions> з тим же простором імен URI, що і у атрибута targetNamespace.)

Багато в чому <wsdl: portType> можна вважати логічним еквівалентом інтерфейсу Java, так що елементи <wsdl: operation> еквівалентні методам, елементи <wsdl: input> - параметрам методів, елементи <wsdl: output> - результатами методів, а елементи <wsdl : fault> - перевіряється винятків. Ці відповідності використовуються при генеруванні коду Java з WSDL, як і в більшості інструментів, що створюють WSDL з існуючого коду Java.

Порівняння SOAP 1.1 і 1.2

SOAP 1.1 широко використовується для Web-сервісів з моменту опублікування специфікації в 2000 році. Версія SOAP 1.2 розроблена при більш широкій підтримці галузі через W3C і опублікована в якості офіційного стандарту W3C у 2007 році. SOAP 1.2 краще документована і чистіше, ніж SOAP 1.1, причому деякі потворні аспекти 1.1 хірургічно видалені. Незважаючи на цю очищену структуру, для більшості Web-сервісів практичних відмінностей між ними небагато. Ймовірно, найбільш істотна особливість SOAP 1.2 полягає в тому, що це єдиний офіційно підтримуваний спосіб використання розширеної підтримки SOAP-вкладень XML-binary Optimized Packaging (XOP) і SOAP Message Transmission Optimization Mechanism (MTOM). У циклі Web-сервіси Java я до сих пір використовував SOAP 1.1, тому що деякі старі стеки не підтримують SOAP 1.2, але для розробки нових Web-сервісів 1.2, ймовірно, є найкращим вибором.

Елементи <wsdl: binding> являють собою екземпляр абстрактного інтерфейсу, визначеного <wsdl: portType>, який видно в лістингу 2 на початку BookServerImpl.wsdl. Атрибут type містить повне ім'я типу порту, реалізованого в прив'язці.

Дочірні елементи <wsdl: binding> містять детальну інформацію про спосіб реалізації типу порту. Дочірні елементи з простору імен WSDL відповідають елементам <wsdl: portType> і повинні використовувати те ж значення name - а не посилання з уточненням простору імен, як у випадку <wsdl: portType>. На малюнку 1 цей зв'язок показана пунктирними лініями на рівні <wsdl: operation>. Та ж зв'язок по імені відноситься і до дочірнім елементам <wsdl: input> / <wsdl: output> / <wsdl: fault> елементів <wsdl: operation>. Незважаючи на таке повторне використання одних і тих самих імен елементів, зміст цих елементів істотно відрізняється, коли це дочірні елементи <wsdl: binding>, а не елементу <wsdl: portType>.

Розширення, що визначаються WSDL, вступають в гру в <wsdl: binding>. Дочірній елемент <soap binding> використовується у визначенні сервісу SOAP (єдиний тип сервісу, що допускається BP WS-I, хоча WSDL 1.1 допускає ще і прив'язки HTTP). Цей елемент <soap: binding> використовує обов'язковий атрибут transport для визначення виду транспорту, що використовується прив'язкою. (HTTP, як видно зі значення http://schemas.xmlsoap.org/soap/http в лістингу 2 , - це єдиний вибір, дозволений ВР WS-I.) Необов'язковий атрибут style дозволяє вибирати між стилями rpc і document для подання XML-даних (найбільш поширене значення document відповідає повідомленнями з використанням елементів визначення схеми, а не типу).

Усередіні шкірного Дочірнього елемента <wsdl: operation> елемента <wsdl: binding> елемент <soap: operation> может використовуват для вказівки значення SOAPAction з метою ідентіфікації Запитів виклику цієї операции (і потенційно такоже для перевізначення Вибори стилю document або rpc, зазначеним елементом <soap : binding>, хоча BP WS-I забороняє таке использование). КОЖЕН дочірній елемент <wsdl: input> / <wsdl: output> / <wsdl: fault> містіть Інший додатковий елемент, Який в лістінгу 2 завжди є елементом <soap: body> (що вказує, що дані повідомлення передаються в тексті листа SOAP - дані і навіть помилки можна передавати також в заголовках SOAP, хоча я не рекомендую це) для <wsdl: input> або <wsdl: output>, або його еквівалент <soap: fault>, який використовується з <wsdl: fault>.

Останнім компонентом опису сервісу WSDL є елемент <wsdl: service>, який складається з групи елементів <wsdl: port>. Кожен елемент <wsdl: port> пов'язує адреса доступу з <wsdl: binding>. Адреса доступу міститься у вкладеному додатковому елементі <soap: address>.

Робота з WSDL

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

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

Для роботи з WSDL-документами на мові Java побудовано безліч різних моделей, в тому числі широко використовувана мова опису Web-сервісів для Java Toolkit (WSDL4J), який являє собою еталонну реалізацію JSR 110 (див. Розділ ресурси ). Жодна з цих моделей не відповідає тому, що я збирався зробити, зважаючи на двоякою постановки завдання: по-перше, читання WSDL-документів в будь-який напіврозумні формі і повідомлення про помилки і відхилення від практичних рекомендацій, і по-друге, написання безпомилкових WSDL- документів, переформатованих в форму, відповідну практичним рекомендаціям. WSDL4J, наприклад, не зберігає порядок вводяться елементів, так щоб можна було повідомляти про проблеми порядку їх слідування, і не виконує жодних визначення схеми, так що його не можна безпосередньо використовувати для перевірки посилань з елементів <wsdl: part>. Так що мені довелося вибирати між більш реалістичною постановкою завдання і написанням своєї власної моделі. Природно, я вирішив написати власну модель.

модель WSDL

Валідація та верифікація

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

Раніше я вже частково реалізував модель WSDL для використання з прив'язкою даних JiBX в рамках проекту JiBX / WS. Ця модель призначена тільки для виведення і включає відносно невелике число класів, які в деяких випадках об'єднують дані з вкладених елементів структури WSDL XML (<wsdl: message> в поєднанні з одним дочірнім елементом <wsdl: part>, <wsdl: input>, < wsdl: output> і <wsdl: fault> всередині <wsdl: binding> в поєднанні з елементом <soap: body> або <soap: fault> і т.д.). Ця компактна структура класів полегшила побудова підмножини WSDL-документів, підтримуваних структурою, але коли я став розглядати можливість створення інструменту верифікації та реструктуризації на базі цієї моделі, я зрозумів, що модель для підтримки введення, можливо, погано структурованого WSDL повинна бути ближче до XML- поданням.

Ще один варіант - генерування коду зі схеми BP WS-I для WSDL 1.1. Побачивши це, я зрозумів, що просте використання створених класів безпосередньо призведе до плутанини, так як схема включає надлишкові типи, а також деякі незручні конструкції, які використовуються для представлення різних моделей обміну повідомленнями (деякі з яких потім були заборонені текстом BP WS-I) .

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

У лістингу 3 показана частина класу Definitions, відповідна кореневого елементу <wsdl: definitions>.

Лістинг 3. Клас Definitions (частково)
public class Definitions extends ElementBase {/ ** Перерахування дочірніх елементів в очікуваному порядку. * / Static enum AddState {invalid, imports, types, message, portType, binding, service}; / ** Список дозволених імен атрибутів. * / Public static final StringArray s_allowedAttributes = new StringArray (new String [] { "name", "targetNamespace"}); / ** Валідація використовуваного контексту. * / Private ValidationContext <ElementBase, Definitions> m_validationContext; / ** Поточний стан (використовується для перевірки порядку, в якому додаються * / / ** дочірні елементи). * / Private AddState m_state; / ** Ім'я цього визначення. * / Private String m_name; / ** Цільовий простір імен WSDL. * / Private String m_targetNamespace; / ** Список всіх імпортованих дочірніх елементів. * / Private List <Import> m_imports = new ArrayList <Import> (); / ** Список всіх типів дочірніх елементів. * / Private List <Types> m_types = new ArrayList <Types> (); / ** Список всіх повідомлень дочірніх елементів. * / Private List <Message> m_messages = new ArrayList <Message> (); / ** Список всіх дочірніх елементів portType. * / Private List <PortType> m_portTypes = new ArrayList <PortType> (); / ** Список всіх прив'язок дочірніх елементів. * / Private List <Binding> m_bindings = new ArrayList <Binding> (); / ** Список всіх сервісів дочірніх елементів. * / Private List <Service> m_services = new ArrayList <Service> (); / ** Відображення кваліфікованого імені на повідомлення в цьому визначенні. * / Private Map <QName, Message> m_nameMessageMap = new HashMap <QName, Message> (); / ** Відображення кваліфікованого імені на тип порту в цьому визначенні. * / Private Map <QName, PortType> m_namePortTypeMap = new HashMap <QName, PortType> (); / ** Відображення кваліфікованого імені на повідомлення в цьому визначенні. * / Private Map <QName, Binding> m_nameBindingMap = new HashMap <QName, Binding> (); / ** Відображення кваліфікованого імені на сервіс в цьому визначенні. * / Private Map <QName, Service> m_nameServiceMap = new HashMap <QName, Service> (); ... / ** * Перевірка перехідних станів між різними типами дочірніх елементів. * Якщо елементи не знаходяться в очікуваному порядку, * для звіту зазначається перший елемент поза очікуваного порядку. * @Param state new add state * @param comp element component * / private void checkAdd (AddState state, ElementBase comp) {if (m_state! = State) {if (m_state == null || (m_state! = AddState.invalid && state.ordinal ()> m_state.ordinal ())) {// перехід до іншого типу дочірніх елементів m_state = state; } Else if (state.ordinal () <m_state.ordinal ()) {// звіт про дочірніх елементах поза очікуваного порядку m_validationContext.addWarning ( "Child element of wsdl: definitions out of order", comp); m_state = AddState.invalid; }}} ... / ** * Додавання немаршаллізірованного дочірнього елемента wsdl: message. * Тут же повідомлення індексується на ім'я для доступу з метою валідації. * * @Param child * / public void addMessage (Message child) {checkAdd (AddState.message, child); m_messages.add (child); addName (child.getName (), child, m_nameMessageMap); } ...

Організація даних дочірніх елементів в лістінгу 3 показує, яким чином модель підтримує як загальну форму введення, так і форму виведення відповідно до практичними рекомендаціями. Замість єдиного списку дочірніх елементів всіх типів, використовуються окремі списки для кожного типу. Прив'язка введення JiBX обробляє дочірні елементи як невпорядкований набір, викликаючи специфічний для даного типу елементів set-метод щоразу, коли дочірній елемент знаходиться не на своєму місці. Замість того щоб замінювати будь-яка з попередній значень, set-метод додає екземпляр в типізований список, як видно з set-методу addMessage (), який використовується для дочірніх елементів <wsdl: message>. Кожен set-метод запускає також перевірку стану для вилову невпорядкованих елементів.

У будь-якому з елементів WSDL дозволені додаткові атрибути і елементи (як правило, всі атрибути або елементи, які не використовують простір імен WSDL 1.1). Прикладом таких додаткових елементів служать конфігурації WS-Policy, вбудовані в WSDL-документи з попередніх статей даного циклу, як і посилання на фактичні політики. Найкраще, щоб ці додаткові елементи передували будь-яким дочірнім елементам з простору імен WSDL 1.1, і саме так вони обробляються в прив'язці виведення. Прив'язка введення обробляє додаткові елементи і атрибути за допомогою коду базового класу з класів елементів WSDL, що не показаного в лістінгу 3 , І дозволяє елементам слідувати в будь-якому порядку (генеруючи попередження, якщо вони слідують за елементом з простору імен WSDL 1.1).

Модель обробляє відомі елементи, використовуючи окремі прив'язки для кожного додаткового простору імен, кожна з яких має свій власний набір класів. Я розгляну обробку цих додаткових елементів більш докладно в наступному випуску Web-вервісов Java, де буде докладніше представлений і вихідний код.

Деяка базова верифікація даних WSDL виконується в міру додавання немаршаллізованних об'єктів, що відповідають елементам, в деревоподібну структуру WSDL-документа, як показано в коді addMessage () в кінці лістингу 3 . Цей код використовує метод checkAdd () для перевірки порядку проходження дочірніх елементів і метод addName () для перевірки того, що представлено припустиме ім'я (текст відповідає типу схеми NCName і значення унікально в межах типу елемента), і відображення імені на об'єкт. Але це тільки перевірка самої основної інформації для окремого елемента; для перевірки інших властивостей кожного елемента і взаємозв'язків між елементами необхідний додатковий код верифікації.

JiBX дозволяє викликати обробники для користувача розширень в рамках процесу маршаллінг і демаршаллінга. Для виконання логіки верифікації модель WSDL використовує один з таких додаткових обробників, метод post-set. Метод post-set викликається після завершення демаршаллінга пов'язаного об'єкта, так що це часто хороший спосіб виконання перевірок типу верифікації об'єктів. У разі перевірки WSDL найпростіший підхід - це виконання всієї верифікації об'єктів з одного методу post-set для кореневого елемента <wsdl: definitions>. Такий підхід дозволяє уникнути проблем прямих посилань на компоненти WSDL-документа, коли компоненти не дотримуються в очікуваному порядку.

інші доповнення

У цій статті викладені основи структури та використання WSDL і введення в модель даних Java для WSDL, призначену для підтримки верифікації WSDL-документів і їх перетворення в форму, відповідну практичним рекомендаціям.

наступна стаття jsp?search_by=java+web+services:> цього циклу продовжить цю тему, розглядаючи проблеми, що часто зустрічаються при написанні тверджень WS-Policy і WS-SecurityPolicy. Крім того, в ній буде більш детально розглянута модель WSDL і процес верифікації, в тому числі розширення моделі з включенням тверджень WS-Policy / WS-SecurityPolicy, вбудованих в WSDL.

Ресурси для скачування

Схожі тими

  • оригінал статті . (EN)
  • WSDL 1.1 : Офіційна посилання на стару, але як і раніше широко використовувану версію WSDL.
  • Схеми WSDL 1.1: специфікація WSDL 1.1 включає в себе визначення схеми , Що не відповідає тексту. Згодом ця схема була замінена ось цієї , Хоча текст WSDL 1.1 так і не був оновлений відповідно до цієї пізнішої схемою. Нарешті, WS-I запропонувала третю версію схеми WSDL 1.1, яка, ймовірно, є найкращою.
  • WSDL 1.1 Binding Extension for SOAP 1.2 : Доповнює WSDL 1.1 для підтримки SOAP 1.2.
  • WSDL 2.0 частина 0: Введення , WSDL 2.0 частина 1: Основна мова и WSDL 2.0 частина 2: Додатки : Офіційні посилання на стандарт WSDL 2.0.
  • WS-I Basic Profile : WS-I допомогла сформулювати практичні рекомендації щодо застосування WSDL 1.1, а також багато інших аспектів Web-сервісів.
  • XML-binary Optimized Packaging и SOAP Message Transmission Optimization Mechanism : Ці стандарти визначають, як двійкові дані можна логічно вбудовувати в повідомлення SOAP 1.2, що надсилаються окремо, щоб уникнути накладних витрат з кодування. Вони замінюють конкуруючі підходи SOAP Messages with Attachments (SwA) (Широко застосовується в стеках Java, але не в .NET) і Direct Internet Message Encapsulation (DIME) (Реалізований в .NET, але не в більшості стеків Java), які використовуються для вкладень в SOAP 1.1. У деяких стеках реалізовані також XOP / MTOM для SOAP 1.1 з використанням проекту SOAP 1.1 Binding for MTOM 1.0 .
  • Web Services Description Language for Java Toolkit (WSDL4J) : Еталонна реалізація JSR 110: Java API для WSDL - широко використовувана бібліотека для роботи з WSDL-документами.

Підпішіть мене на ПОВІДОМЛЕННЯ до коментарів

Jsp?

Новости