Язык WSDL. Структура WSDL-документа. Способы создания. Режимы операции WSDL. Описание Web Services на языке WSDL

Заголовок топика – это действительно вопрос, т.к. я сам не знаю, что это и впервые попробую поработать с этим в рамках настоящей статьи. Единственное, что могу гарантировать, что код, представленный ниже, будет работать, однако мои фразы будут лишь предположениями и догадками о том, как я сам все это понимаю. Итак, поехали…

Введение

Начать надо с того, для чего создавалась концепция веб-сервисов. К моменту появления этого понятия в мире уже существовали технологии, позволяющие приложениям взаимодействовать на расстоянии, где одна программа могла вызвать какой-нибудь метод в другой программе, которая при этом могла быть запущена на компьютере, расположенном в другом городе или даже стране. Все этого сокращенно называется 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 ru. 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 ru. 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. MalformedURLException; // классы, чтобы пропарсить xml-ку c wsdl описанием // и дотянуться до тега service в нем import javax. xml. namespace. QName; import javax. xml. ws. Service; // интерфейс нашего веб-сервиса (нам больше и нужно) import ru. 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 // 1-ый аргумент смотрим в атрибуте targetNamespace // 2-ой аргумент смотрим в атрибуте 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.

Элементы расширения связывания используются для указания конкретной грамматики для входящих (3) и исходящих (4) сообщений, сообщений об ошибках (5). Также может указываться информация уровня операции (2) и уровня связывания (1).

Элемент связывания operation содержит данные для одноимённой операции связанного типа порта. Однако имя операции в общем случае не является уникальным (пример: перегрузка методов / функций — использование одинаковых имён с различными сигнатурами), потому его может быть недостаточно для однозначного определения целевой операции типа порта. В таких случаях целевая операция адресуется с помощью дополнительного задания соответствующих имён элементов wsdl:input и wsdl:output с помощью атрибута name .

Связывание должно устанавливать только один протокол.

Связывание не должно содержать информации об адресе.

Порт

Порт определяет отдельную конечную точку посредством установки адреса для связывания.

  1. <wsdl :definitions .... >
  2. <wsdl :service .... > *
  3. <wsdl :port name = "nmtoken" binding = "qname" > *
  4. <-- extensibility element (1) -->
  5. wsdl :port >
  6. wsdl :service >
  7. wsdl :definitions >

Атрибут name задаёт уникальное имя среди всех портов в рамках WSDL-документа. Атрибут binding типа QName содержит ссылку на связывание (см.).

Элементы расширения (1) используются для задания адреса.

Порт не должен задавать более одного адреса.

Порт не должен содержать любую информацию связывания, отличную от адреса.

Служба

Служба объединяет вместе набор связанных портов.

  1. <wsdl :definitions .... >
  2. <wsdl :service name = "nmtoken" > *
  3. <wsdl :port .... /> *
  4. wsdl :service >
  5. wsdl :definitions >

Атрибут name задаёт уникальное имя среди всех служб, определённых в рамках WSDL-документа.

Порты внутри службы связаны следующим образом:

  • Порты не взаимодействуют друг с другом (т.е. выход одного порта не является входом другого).
  • Если служба имеет несколько портов, которые разделяют общий тип порта, но используют разные связывания, либо имеют различные адреса, такие порты являются альтернативными. Каждый такой порт реализует логически эквивалентное поведение (в рамках ограничений транспорта и формата сообщений, накладываемых соответствующим связыванием). Это позволяет клиенту выбирать конкретный порт для обмена на основе различных критериев (поддержка транспортного протокола и т.д.).
  • Рассмотрев порты, можно определить поддерживаемые службой типы портов. На основе этих данных клиент может определить возможность взаимодействия с конкретной службой. Это полезно, если подразумевается связь между операциями из разных типов портов, и для выполнения определённой задачи требуется поддержка службой всех необходимых типов портов.
  1. Это вольный, частичный, дополненный перевод документа Web Services Description Language (WSDL) 1.1 от 15 Марта 2001
  2. Несклоняемыми написанными латиницей терминами оперировать крайне неудобно, к тому же они однозначно переводятся. Поэтому исходное имя даётся только при введении нового термина, а далее по тексту используется русский перевод.

Язык описания Web-сервисов (WSDL)

В последних нескольких примерах вы могли видеть отдельные фрагменты WSDL-кода. Напомним, что WSDL – это основанная на XML грамматика, предназначенная для описания возможностей взаимодействия внешних клиентов с Web-методами, доступными по данному адресу URL в рамках каждого из поддерживаемых протоколов связи. Во многих отношениях WSDL-документ может рассматриваться, как "контракт" между клиентом Web-сервиса и самим Web-сервисом. Это еще один метаязык. В частности, WSDL используется для описания следующих характеристик любого доступного Web-метода:

Имя Web-метода XML;

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

Тип возвращаемого значения (если таковое предусмотрено);

Условия вызова HTTP GET, HTTP POST и SOAP.

В большинстве случаев WSDL-документы генерируются автоматически соответствующим Web-сервером. Напомним, что при добавлении суффикса?wsdl к адресу URL, указывающему на файл *.asmx, Web-сервер генерирует WSDL-документ для указанного Web-сервиса XML.

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

Но если IIS автоматически генерирует WSDL-документ для данного Web-сервиса XML, зачем тогда нужно глубокое понимание синтаксиса генерируемых WSDL-данных? Ответ обычно зависит от того, как ваш сервис будет использоваться внешними приложениями. В случае Web-сервисов XML, предназначенных для "внутреннего" использования, сгенерированного Web-сервером WSDL-кода будет, как правило, достаточно.

Между тем. вполне возможно начать разработку Web-сервиса XML с создания WSDL-документа вручную (об этом уже говорилось выше). Главная идея начала разработки с создания WSDL-документа связана с вопросами совместимости. Вспомните о том, что до появления спецификации WSI различные инструменты построения Web-сервисов нередко генерировали несовместимые WSDL-описания. Если начинать разработку с WSDL-кода, вы можете построить документ так, как требуется.

Как вы можете догадаться, для начала разработки Web-сервиса XML с создания WSDL-документа требуется очень хорошее знание грамматики WSDL, обсуждение которой в контексте этой главы не предусмотрено. Но мы рассмотрим базовую структуру WSDL-документа. Разобравшись в основах, вы сможете оценить пользу утилиты командной строки wsdl.exe.

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

Определение WSDL-документа

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

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

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

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

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

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

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

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

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

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

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

‹/wsdl :definitions›

В контексте корневого элемента вы можете найти пять подчиненных элементов. Общий вид WSDL-документа должен быть примерно таким.

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

‹wsdl:definitions …›

‹wsdl:types›

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

‹wsdl:/types›

‹wsdl:message›

‹!-- Формат сообщений - -›

‹wsdl:/message›

‹wsdl:portType›

‹!-- Информация портов - -›

‹wsdl:/portType›

‹wsdl:binding›

‹!-- Информация связывания - -›

‹wsdl:/binding›

‹wsdl:service›

‹!-– Информация о самом Web-сервисе XML - -›

‹wsdl:/service›

‹wsdl:/definitions›

Как и следует ожидать, каждый из этих подчиненных элементов будет содержать дополнительные элементы и атрибуты, уточняющие описание имеющихся возможностей. Давайте по очереди рассмотрим наиболее важные из допустимых узлов.

Элемент ‹types›

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

‹s:еlement name= "Subtract"›

‹s:sequence›

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

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

‹/ s:sequence›

‹/s:complexType›

‹/s:element›

Целое число, возвращаемое методом Subtract(), также описывается в рамках элемента ‹types›.

‹s:element name= "SubtractResponse "›

‹s:complexType›

‹s:sequence›

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

‹/s:sequence›

‹ /s:complexType›

‹/s:element›

Если вы имеете Web-метод, возвращающий или получающий пользовательские типы данных, они также появятся в контексте элемента ‹complexType›. Детали того, как с помощью Web-метода сделать доступными пользовательские типы данных.NET, мы рассмотрим позже. Для примера предположим, что вы определили Web-мeтод, возвращающий структуру с именем Point.

public struct Point {

public string pointName;

WSDL-описание для этой "сложной структуры" будет выглядеть примерно так.

‹s:complexType name="Point "›

‹s:sequence›

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

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

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

‹/s:sequence›

‹/s:complexType›

Элемент ‹message›

Элемент ‹message› используется для определения формата обмена запросами и ответами данного Web-метода. Поскольку один Web-сервис позволяет передачу множества сообщений между отправителем и получателем, одному WSDL-документу позволяется определять множество элементов ‹message›. Как правило, в этих определениях используются типы, указанные в рамках элемента ‹types›.

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

‹wsdl:message name="SubtractSoapIn "›

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

‹/wsdl:message›

‹wsdl: message name="SubtractSoapOut "›

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

‹/wsdl:message›

Здесь вы видите только связь SOAP соответствующего сервиса. Как говорилось в начале этой главы, Web-сервисы XML могут вызываться с помощью SOAP или HTTP-методов GET и POST. Но если вы разрешите связь HTTP POST (соответствующие объяснения будут предложены позже), генерируемый WSDL-код должен продемонстрировать следующие данные ‹message›.

‹wsdl: message name="SubtractHttpPostIn "›

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

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

‹wsdl:/message›

‹wsdl:message name="SubtractHttpPostOut "›

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

‹wsdl:/message›

Элементы ‹message› сами по себе не слишком полезны. Однако на эти определения сообщений ссылаются другие части WSDL-документа.

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

Элемент ‹portType›

Элемент ‹portType› определяет различные связи, которые могут возникать между клиентом и сервером, и каждая такая связь представляется вложенным элементом ‹operation›. Несложно догадаться, что самыми типичными операциями здесь должны быть SOAP, HTTP GET и HTTP POST. Однако есть и другие операции. Например, односторонняя операция позволяет клиенту отправить сообщение данному Web-серверу, но не получить ответ (это похоже на вызов метода без ожидания возвращаемого значения). Операция "требование-ответ" позволяет серверу отправить, запрос во время ответа клиента (что можно рассматривать, как дополнение операции "запрос-ответ").

Чтобы проиллюстрировать формат необязательного вложенного элемента ‹operation›, рассмотрим WSDL-определение для метода Subtract().

‹wsdl portType name="CalculatorWebServiceSoap "›

‹wsdl:operation name="Subtract "›

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

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

‹ /wsdl:operation›

‹wsdl:/portType›

Обратите внимание на то, как элементы ‹input› и ‹output› ссылаются на соответствующее имя сообщения, определенное в рамках элемента ‹message›. Если бы для метода Subtract() был разрешен HTTP-метод POST, вы бы увидели следующий дополнительный элемент ‹operation›.

‹wsdl:portType name="CalculatorWebServiceHttpPost"›

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

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

‹ wsdl:/operation›

‹wsdl:/portType›

Наконец, учтите то, что если данный Web-метод описан с помощью свойства Description, элемент ‹operation› будет содержать вложенный элемент ‹documentation›.

Элемент ‹binding›

Этот элемент указывает точный формат обмена GET, POST и SOAP. Это самый "многословный" из всех элементов, содержащихся в контексте корневого элемента ‹definition›. Вот, например, определение элемента ‹binding› с описанием того, как вызывающая сторона может взаимодействовать с Web-методом MyMethod(). используя SOAP.

‹wsdl:binding name="СаlculatorWebServiceSoap12" type="tns:CalculatorWebServiceSoap "›

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

‹wsdl:operation name= "Subtract "›

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

‹wsdl:input›

‹soap12:body use="literal " /›

‹/wsdl:input›

‹wsdl:output›

‹soap12:body use="literal " /›

‹/wsdl:output›

‹/wsdl:operation›

‹/wsdl:binding›

Элемент ‹service›

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

‹wsdl:service name="CalculatorWebService "›

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

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

‹/wsdl:documentation›

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

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

‹/wsdl:port›

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

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

‹/wsdl:port›

‹/wsdl:service›

Итак, как видите, WSDL-код, автоматически возвращаемый сервером ITS, не является сверхсложным, но, поскольку WSDL представляет собой грамматику на основе XML, этот код достаточно "многословен". Тем не менее, теперь вы должны лучше понимать роль WSDL, так что давайте рассмотрим немного подробнее протоколы связи Web-сервисов XML.

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

WSDL (Web Services Description Language ) версии 1.1 был опубликован 15 марта 2001 года. WSDL - это формат, базирующийся на XML и использующийся для описания сетевых cервисов, при помощи сообщений, содержащих информация о том как осуществлять доступ к конкретному веб-сервису. WSDL расширяем, что позволяет описывать услуги (сервисы) и их сообщения независимо от того, какие форматы сообщений или сетевые протоколы используются для транспорта, однако, чаще всего используется WSDL 1.1 вместе с SOAP 1.1, HTTP GET/POST и MIME. Поскольку WSDL был разработан совместно с SOAP, в его разработке участвовали все те же фирмы Microsoft, Ariba и IBM. Если рассматривать документ WSDL интуитивно, то можно сказать, что он позволяет ответить на 4 вопроса :

1) что вы делаете? Ответ на этот вопрос дается в форме пригодной как для восприятия человеком так и форме воспринимаемой машиной. Ответ для чел-ка в тегах: <name />, <documentation />, для машины - <message />, <pointType >

2) на каком языке вы разговариваете? (какие типы вы используете?)Ответ в теге: <types />

3) как я буду с вами общаться? (как клиент будет обращаться к веб-службе?):HTTP или SMTP. Ответ находится в <binding />

4) где мне вас найти? (где я могу найти эту веб-службу или какой у нее URL?). Ответ находится: <service />

Структура:

Каждый документ WSDL можно разбить на три логические части:

1. определение типов данных - определение вида отправляемых и получаемых сервисом XML сообщений

2. абстрактные операции - список операций, которые могут быть выполнены с сообщениями

3. связывание сервисов - способ, которым сообщение будет доставлено

Документы WSDL можно создавать вручную, однако строгая формализация языка WSDL позволяет автоматизировать процесс написания WSDL -документов. Многие интсрументальные средства создания Web-служб содержат утилиты, которые автоматичеки создают WSDL -файлы, описывающие готовые Web-службы. Например средство создания Web-служб Apache Axis содержит в своем составе класс Java2WSDL , создающий WSDL -файл по классу или интерфейсу Java, описывающему Web-службу. Пакет IBM WSTK, в состав которого входит Axis , содержит утилиту java2wsdl , создающую и запускающую объект из этого класса. Она работает из командной строки.

Элементы WSDL-документа

Опишем наиболее часто употребляемые теги WSDL:

Тег – это корневой тег всех WSDL-документов. Он определяет несколько пространств имен:

1)target Name space – это пространство имен нашей веб-службы

2)xmlns – стандартное пространство имен документа WSDL

3)xmlns: SOAP_ENC – пространство имен используемое для описания кодировки SOAP


4)xmlns: impl и intf – пространство имен реализации и определения нашей веб-службы

· Документ для определения веб-службы

· Документ для реализации веб-службы

Для простоты, как правило, используют 1 файл, который содержит всю информацию

Элемент - предоставляет информацию о данных, которые передаются от одной конечной точки к другой.

Для описания вызова RPC необходимо создать входной сообщение и выходное сообщение.

В рамках этого элемента можно указать параметры метода с помощью элемента

Элемент описывает и определяет операции или методы поддерживаемые веб-службой

Операции могут иметь входные сообщения, а также сообщения об ошибках.

Элемент - описывает, как операции определенные в типе порта будут передаваться по сети. Т.к. элемент использует тип порта, то он должен указывать тип определенный где-то ранее в документе.

Элемент - указывает где найти веб службу

Элемент import . Очень часто элемент service выделяется в свой wsdl документ из соображений практичности.

Для того, чтобы позволить собрать из нескольких wsdl документов один используется элемент import. Он позволяет включать один wsdl документ в другой.

Элемент types позволяет указать типы передаваемых данных если они не являются стандартными.

WSDL поддерживает 4 режима операций:

· операции типа one-way или односторонние операции. Сообщение посылается конечной точке службы. В этом случае операция описывается только одним входным сообщением.

· Request-Response – режим запрос-ответ. Этот режим операции является наиболее общим. В этом режиме описание операции содержит входное и выходное сообщение и необязательное сообщение об ошибке.

· Операция типа требование-ответ. В этом режиме конечной точкой является клиент другой конечной точки. Формат операции похож на режим запрос-ответ, но выходные данные перечисляются перед входными данными.

· Операция уведомление. Этот режим – еще одна версия примитива односторонней передачи, в которой конечная точка посылает сообщение а не получает его. Операция содержит только выходное сообщение.

Предисловие

Заказчики заказчиков попросили заказчиков xsd файлы для структур, передаваемых реализуемыми Web-сервисами. Заказчики в ответ предложили заказчикам заказчиков сделать WSDL-ки. Т.о. неожиданно «на ровном месте» возникла необходимость сделать не просто xsd-схемы для валидации данных, а «целые WSDL-ки». Обычно WSDL-ки используются для SOAP, а у нас REST…

Ранее я уже писал про

Введение

Термин Web-сервисы обычно ассоциируется с operation- или action-based сервисами, базирующимися на SOAP или WS* стандартах, таких как WS-Addressing или WS-Security. Термин REST Web-сервисы обычно относится к resource-based архитектуре Web-сервисов, передающих XML через HTTP. Каждый из этих архитектурных стилей имеет собственное место, но до недавнего времени, WSDL стандарт не поддерживал оба эти стиля. WSDL 1.1 HTTP binding был неадекватен для описания взаимодействия с помощью XML по HTTP, т.о. не было формального способа описать REST Web-сервисы с помощью WSDL. Публикация стандарта WSDL 2.0 (который был разработан с учётом необходимости описания REST Web-сервисов) в статусе рекомендации World Wide Web Consortium (W3C) дала язык для описания REST Web-сервисов.

REST — архитектурный стиль трактующий Web как resource-centric приложение. Практически, это означает, что каждый URL в RESTful приложении представляет собой ресурс. URL-и просто понимать и запоминать. Например, книжный магазин может определить URL http://www.bookstore.com/books/ для списка продаваемых книг и http://www.bookstore.com/books/0321396855/ для деталей о конкретной книге с ISBN 0321396855. Это контрастирует с action-centric приложениями, обычно имеющими длинные сложношифованные URL-и, описывающими действия, которые необходимо выполнить, например http://www.bookstore.com/action/query?t=b&id=11117645532&qp=0321396855 . Параметры запроса используются для выбора необходимых данных. Используя пример книжного магазина, указание параметра subject ограничивает тематику книги. Например физика или детективы или к примеру URL http://www.bookstore.com/books/?subject=computers/eclipse — запрос возвращающий список книг про платформу Eclipse.

Термин REST придумал Roy Fielding в своей кандидатской диссертации. Он рассматривал гиперссылки как средство для изменения (хранения) состояния приложения. Гиперлинки хранятся в ресурсах приложения и являются методом изменения состояния приложения, редиректа из одного состояния в другое. Обычно гиперлинки в (X)HTML предназначены для использования людьми, они не использовались в XML, который был предназначен для машинной обработки. Также как и (X)HTML, REST Web-сервисы испльзуют гиперлинки в XML.

Традиционные Web-приложения получают доступ к ресурсам посредством HTTP GET или POST операций. RESTfull приложения работают с ресурсами в стиле «create, read, update, and delete (CRUD)» используя полные возможности HTTP протокола (POST, GET, PUT, and DELETE).

Ещё одно важное замечание о REST приложении: RESTful приложения должны быть stateless. Это означает, что REST приложение не сохраняет никакого состояния сессии на стороне сервера. Вся информация, необходимая для выполнения запроса, передается в самом запросе. (Поэтому на повторяющиеся запросы сервер обязан отвечать одинаково прим. переводчика). Соответственно клиент может кешировать полученные ресурсы, что может значительно ускорить скорость работы приложения там, где сервис явно разрешает это. Чтобы узнать больше про REST, см ссылки к статье.

WSDL и REST

WSDL содержит все детали о веб-сервисе, включая:

    URL веб-сервиса
    Механизмы коммуникации, корые понимает веб-сервис
    Операции, которые может выполнять веб-сервис
    Структура сообщений веб-сервиса

Клиенты могут использовать перечисленные детали для взамодействия с сервисом.

WSDL 2.0 был объявлен рекомендацией W3C в июне 2007. Эта версия WSDL стандарта была выпущена для решения проблем стандарта WSDL 1.1, многие из которых были обнаружены организацией Web Services Interoperability (WS-I). Кроме того в WSDL 2.0 улучшена поддержка HTTP bindings.

WSDL сам является XML — подмножеством формально описывающим веб-сервис. Рассматривайте WSDL описание веб-сервиса как его API контракт с клиентом. В WSDL указывается адрес, допустимые способы передачи информации, интерфейса и типы сообщений веб-сервиса. Короче говоря, описание WSDL содержит всю информацию, необходимую клиенту для использования веб-сервиса.

Применимость WSDL, выходит за пределы его использования в качестве контракта API. Являясь формальным определением, WSDL может быть использован софтом упрощающим реализацию веб-сервисов для таких операций как:

  • Генерирование исходного кода клиентского приложения и сервера для веб-сервиса на разных языках программирования
  • Публикация веб-сервиса
  • Динамическое тестирование веб-сервиса

Большинство программных средств для работы с веб-сервисами включают в себя поддержку WSDL 1.1. Последнее время растёт количество средств разработки веб-сервисов, поддерживающих WSDL 2.0. Проект Apache Web services состоит из двух подпроектов, которые в настоящее время поддерживают WSDL 2.0. Woden — парсер-валидатор WSDL 2.0 на базе Java. Apache Web services проект также предоставляет XSL (XSLT) трансформацию WSDL 2.0 под названием WSDL 2.0 pretty printer , обеспечивающую лучшую человекочитаемость документа WSDL. Axis2 популярный engine веб-сервисов, (тоже от Apache) реализующий генерацию клиентского и серверного Java кода из документа WSDL 2.0.

Описание REST веб-сервиса с помощью WSDL 2.0

Вы создаете книжный магазин, который с продвинутым URL: http://www.bookstore.com . Вы уже создали две службы REST Web:

  • book list — сервис получает список продаваемых у вас книг.
  • book details — сервис получает информацию о конкретной книги.

Ответ возвращается в XML-документах.

Элемент interface определяет список операций веб-сервиса, включая описание входных, выходных сообщений и сообщений об ошибках для операций, а также порядка передачи.

Элемент binding определяет, средства коммуникации клиента с веб-сервисом. В случае REST веб-сервисов, в качестве средства коммуникации указывается HTTP.

Элемент service ассоциирует адреса веб-сервиса с конкретными интерфейсами (interface) и средствами коммуникации (binding). (Т.е. задает соответствие URL операции веб-сервиса и элементу binding ).

Привязываем book list к HTTP

Элемент binding задает привязку веб-сервиса к конкретному протоколу передачи данных. Для привязки book list сервиса к HTTP нужно указать значение http://www.w3.org/ns/wsdl/http для атрибута type элемента binding .

Элемент binding может опционально ссылаться на interface . Оставьте атрибут interface пустым. Вы создадите его в следующем разделе. Если interface ассоциирован с binding , тогда binding элемент может опционально определять дочерний элемент operation , являющийся зеркальным для interface operation элемента. Вам нужно создать заглушку элемента operation и заполнить ссылку на operation позже после создания interface .

Существует 4 HTTP communication метода

  • DELETE

Book list сервис читает запрос и соответственно оперирует с помощью HTTP GET. Установите метод GET для элемента operatioin используя атрибут method из WSDL 2.0 HTTP namespace. Для использования этого атрибута, вам нужно сначала определить namespace http://www.w3.org/ns/wsdl/http в элементе description .

Book list сервис binding определен на нижеследующем листинге. Укажите теперь binding в элементе endpoint : tns:BookListHTTPBinding.

The bookstore"s book list service.

Определение book list service operation

So far you’ve learned how to address and communicate with the book list Web service. Next you specify the book list service operation, which describes what the book list service does.

Итак, вы научились задавать address и задавать binding (способ коммуникации) для веб-сервиса. Далее необходимо задать service operation, определяющую что делает book list веб-сервис.

Элемент interface и его дочерний operation элемент используются для определения сервисных операций. В случае с book list, вы определяете одну операцию getBookList, возвращающую список книг.

Затем определите три атрибута для элемента operation:

Pattern

Используется для указания шаблона обмена сообщениями message exchange pattern (MEP) для операции. MEP определяет последовательность сообщений для операции и их направление. В этом случае необходимо указать значение http://www.w3.org/ns/wsdl/in-out чтобы указать, что веб-сервис получает одно входное сообщение просьбой о списке книг, и посылает одно выходное сообщение со списком книг. Для поддержки этого MEP, указажите дочерние элементы input и output для элемента operation . Эти элементы используют элементы описанные в XML schema, определяющие структуры сообщений. Подробности в следующем разделе.

Style

Используется для указания дополнительной информации о работе. Укажите значение http://www.w3.org/ns/wsdl/style/iri , накладывающее ограничения на содержание входных элементов, такие как требование, что это только использовать XML schema элементы.

wsdlx:safe

wsdlx:safe: From the WSDL extensions namespace, this attribute declares that this operation is idempotent. This type of operation doesn’t modify the resource and can therefore be called many times with the same results. To make use of this element, declare the WSDL extensions namespace http://www.w3.org/ns/wsdl-extensions on the description element.

Этот атрибут из WSDL extentions namespace. Он определяет, что операция является idempotent . Эта операция не модифицирует ресурс, поэтому может быть вызвана многократно с одинаковыми результатами. Чтобы использовать этот элемент, нужно объявить namespace WSDL extentions http://www.w3.org/ns/wsdl-extensions в корневом элементе (элементе description).

Вы можете найти предопределенные Message Exchange Patterns, styles и wsdlx:safe определения по ссылке WSDL 2.0 Part 2: Adjuncts

Ниже приведено определение book list сервиса с добавленным описанием interface . После добавления interface теперь можно изменить binding operation элемент чтобы указать ссылки на описанные interface и operation.

The RESTful HTTP binding for the book list service. The bookstore"s book list service.

Определение сообщений сервиса book list operation

Веб-сервис book list использует два сообщения: входное и выходное. Вы должны описать структуры этих сообщений, чтобы клиентские программы знали что отправлять в адрес сервиса и что ожидать обратно.

WSDL 2.0 supports multiple type systems for describing the message content, but XML schema is the only one in use. This section doesn’t cover the details of XML schema. XML schema is used in many other applications, like WSDL 1.1, and there are many good articles about it. This section highlights how to use XML schema for the book list REST Web service and how to use additional attributes defined by WSDL 2.0 to annotate a schema attribute.

WSDL 2.0 поддерживает множество систем определения типов, но на практике используются только XML schema. Эта статья не вдается в детали XML schema. XML schema используется во многих других приложениях, например, WSDL 1.1, и есть много хороших статей о нем. (). В этом разделе демонстрируется, применение XML schema применительно к конкретному примеру REST сервиса book list, а также использование дополнительных атрибутов определенных в WSDL 2.0 для аннотации schema атрибута.

Чтобы описать 2 сообщения для book list, необходимо описать 2 глобальных элемента.

  • getBookList представляет собой входное сообщение. Он содержит последовательность элементов, включая каждый параметр запроса, позволенный для сервиса: uthor, title, publisher, subject и language . Внутри getBookList сообщения могут использоваться только элементы, потому что выбран IRI style для interface operation.
  • bookList представляет собой выходное сообщение. Он содержит последовательность book элементов. Каждый book элемент в свою очередь содержит title и url атрибуты. Атрибут title не требует пояснений. Атрибут url это линк на сервис book details, возвращающий детальную информацию о конкретной книге.

Ваше определение атрибута url использует в свою очередь 2 атрибута из WSDL extensions namespace. Атрибуты wsdlx:interface и wsdlx:binding задают interface и binding для сервиса. Программное обеспечение может использовать эту информацию для автоматического нахождения сервиса. Для использования этих атрибутов, укажите WSDL extentions namespace для элемента schema . Также включите book details namespace из его WSDL 2.0 описания.

XML schema для book list сервиса приведена ниже.

The request element for the book list service. The response element for the book list service.

Для ссылки на input и output элементы, вы должны импортировать схему в ваш WSDL документ. Для импортирования сземы, используйте schema import элемент в разделе types как показано на листинге ниже. Кроме того, необходимо добавить ссылки на getBookList и Booklist элементы в interface operation input и output элементах и добавить пространства имен book list XML schema в корневой элемент WSDL.

Готовый WSDL для book list веб-сервиса.

This is a WSDL 2.0 description of a sample bookstore service listing for obtaining book information. This operation returns a list of books. The RESTful HTTP binding for the book list service. The bookstore"s book list service.

Примечание переводчика

Я позволил себе не переводить summary и ссылки. И то и другое смотреть у автора. в оригинальной статье . Надо сказать язык оригинала весьма тяжёл. Однако, надеюсь, статья окажется полезной.