Wsdl описание веб сервиса vbs построение запроса. Описание 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.

Язык описания 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-код (можете проверить сами, если вас это интересует).

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

Введение

Начать надо с того, для чего создавалась концепция веб-сервисов. К моменту появления этого понятия в мире уже существовали технологии, позволяющие приложениям взаимодействовать на расстоянии, где одна программа могла вызвать какой-нибудь метод в другой программе, которая при этом могла быть запущена на компьютере, расположенном в другом городе или даже стране. Все этого сокращенно называется 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.javarush.ru/" , "HelloWebServiceImplService" ) ; // Теперь мы можем дотянуться до тега service в wsdl описании, Service service = Service. create (url, qname) ; // а далее и до вложенного в него тега port, чтобы // получить ссылку на удаленный от нас объект веб-сервиса HelloWebService hello = service. getPort (HelloWebService. class ) ; // Ура! Теперь можно вызывать удаленный метод System. out. println (hello. getHelloString ("JavaRush" ) ) ; } } Максимум комментариев по коду я дал в листинге. Добавить мне нечего, поэтому запускаем (Shift+F10). Мы должны в консоли увидеть текст: Hello, JavaRush! Если не увидели, то видимо забыли запустить веб-сервис.

Заключение

В данном топике был представлен краткий экскурс в веб-сервисы. Еще раз скажу, что многое из того, что я написал – это мои догадки по поводу того, как это работает, и поэтому мне не стоит сильно доверять. Буду признателен, если знающие люди меня поправят, ведь тогда я чему-нибудь научусь. UPD.

В главе 2 мы говорили о том, что после создания Web-службы на сервере в виде сервлета, страницы JSP, JWS-файла, компонента EJB или другого объекта, следует описать состав и возможности Web-службы на языке, не зависящем от платформы, операционной системы, системы программирования, использованной при создании Web-службы. Это описание регистрируется в общедоступном месте Интернета, например, реестре UDDI или ebXML, или хранится на сервере Web-службы. Описание должно содержать полную и точную информацию обо всех услугах, предоставляемых Web-службой, способы получения услуг, содержимое запроса на получение услуги, формат предоставляемой информации.

Одно из средств точного и единообразного описания Web-услуг - язык WSDL, созданный консорциумом W3C. Этот язык - еще одна реализация XML. Его последняя рекомендованная спецификация всегда публикуется на странице http://www.w3.org/TR/wsdI . Во время написания книги на черновой стадии была версия WSDL 1.2, которую мы и опишем в этой главе.

Состав документа WSDL

Корневым элементом документа XML - описания WSDL - служит элемент . В этом элементе необязательным атрибутом name можно дать имя описанию. Кроме того, это удобное место для введения используемых в описании пространств имен.

Описания WSDL активно используют различные пространства имен. Кроме собственных имен, язык WSDL часто использует имена типов и элементов языка описания схем XSD (см. главу 1) и имена языка протокола SOAP. Пространство имен языка WSDL часто описывается как пространство имен по умолчанию. Идентификатор пространства имен последней на время написания этих строк версии WSDL 1.2 был равен http://www.w3.org/2002/07/wsdl . Целевое пространство имен, идентификатор которого определяется атрибутом обычно получает префикс tns (target namespace).

В корневой элемент вкладываются элементы шести основных и двух дополнительных типов. Все элементы необязательны, их может быть любое количество, за исключением элемента , который может встретиться в документе только один раз. У каждого элемента есть имя, определяемое обязательным атрибутом name. Элементы ссылаются друг на друга с помощью этих имен. Вот элементы, вкладываемые в корневой элемент

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

? - описывает каждое SOAP-послание: запрос, ответ, пересылку документов. В этот элемент вкладываются элементы Описывающие неделимые с точки зрения WSDL части послания. Для посланий процедурного типа каждый элемент Может описывать имя и тип одного аргумента запроса или тип возвращаемого значения. Для посланий документного типа элементы Могут описывать каждую часть послания "multipart/related". Это абстрактное описание затем конкретизируется элементами .

? Описывает интерфейс Web-службы, называемый в языке WSDL пунктом назначения (endpoint) или портом (port) прибытия послания. Он описывается как набор Web-услуг, называемых в языке WSDL операциями. Переводя это описание на язык программирования можно заметить, что порт хорошо соотносится с интерфейсом Java, а каждая операция - с методом этого интерфейса. Операции описываются вложенными элементами , описывающими каждую отдельную услугу. Услуга описывается действиями, которые разбиты на четыре вида. Это два простых действия: "получение послания", "отправка ответа", и два комбинированных действия: "отправка послания - получение ответа" или, наоборот, "получение послания - отправка ответа". Получение и отправка, в свою очередь, описываются вложенными элементами и , а сообщение об ошибке - элементом . Получаемые и отправляемые послания уже должны быть описаны элементами , элементы , И ссылаются на НИХ СВОИМ атрибутом message.

? - перечисляет вложенными элементами Набор портов, связанных с одной Web-службой. Один и тот же порт может быть связан с несколькими службами.

? - описывает конкретный формат пересылки послания: протоколы, такие как SOAP или HTTP, способы упаковки послания, тип его содержимого: HTML, XML или другой MIME-тип послания. Каждый элемент может быть связан с несколькими такими элементами, по одному для каждого способа пересылки. В этот элемент вкладываются элементы, определенные в схеме выбранного протокола.

? < service > - указывает местоположение Web-службы как один или несколько портов. Каждый порт описывается вложенным элементом Содержащим адрес интерфейса Web-службы, заданный по правилам выбранного в элементе способа пересылки.

Кроме этих шести основных элементов есть еще два вспомогательных элемента.

? - включает файл с XSD-схемой описания WSDL или другой WSDL-файл.

Комментарий. Его можно включить в любой элемент

описания WSDL.

Можно сказать, что элементы , и Показывают, ЧТО есть в описываемой Web-службе, какие услуги она предоставляет, как организованы услуги, какие типы данных у этих услуг.

Элементы объясняют, КАК реализована Web-служба, каков протокол передачи посланий: HTTP, SMTP или какой-то другой, а также задает технические характеристики передачи данных.

Наконец, элементы показывают, ГДЕ находится Web-служба, связывая описание с конкретными адресами Web-службы.

Структура документа WSDL показана в листинге 4.1. Символы в квадратных скобках не содержатся в документе. Они показывают повторяемость элемента или атрибута в описании Web-службы:

Символ [?] означает, что элемент или атрибут может появиться в документе нуль или один раз;

Символ [*] означает, что элемент может появиться нуль или несколько раз;

Символ [+] означает, что элемент может появиться один или несколько раз;

Отсутствие символа в квадратных скобках означает, что атрибут должен появиться ровно один раз.

j Листинг 4.1. Схема WSDL-документа

targetNamespace="nfleH l ra«iij

location="URI-aflpec" /> [*]

Произвольный комментарий

Описания сложных и нестандартных типов.

[*]

[*]

[? ]

Абстрактное описание SOAP-послания как набора составляющих его частей.

[*]

Абстрактное описание Web-службы как набора операций (услуг).

[*]

Описание услуги как получения (input) и отправки (output, fault) посланий.

[?]

Получаемое послание.

[?] [?]

Отправляемое

message="nMH соотв. элемента "> [*] [?]

Отправляемое сообщение об ошибке.

[*]

[+]

type="MMH соотв. элемента "> [*]

[?]

Детали конкретного протокола. Они определяются в схеме

этого протокола. ->

[*]

[?]

Сюда записываются элементы, описывающие детали

конкретной операции. ->

[?]

Сюда записываются элементы, описывающие

детали конкретного получаемого послания. ->

[?]

[?]

Сюда записываются элементы, описывающие

детали конкретного отправляемого послания. ->

[*]

[?]

Сюда записываются элементы, описывающие

детали конкретного сообщения об ошибке. ->

serviceType="MMH соотв. элемента "> [*]

Описание интерфейса Web-службы как набора портов.

binding="nMH соотв. элемента "> [*]

[?]

Сюда записывается обязательный и единственный адрес интерфейса Web-службы, записанный по правилам

протокола, указанного в элементе . ->

Каждый конкретный протокол пересылки посланий - SOAP, HTTP, FTP, SMTP - добавляет к шести основным и двум вспомогательным элементам языка WSDL свои дополнительные элементы, описывающие особенности данного протокола.

Приведем простой пример. В листинге 3.14 мы записали в виде класса Java простейшую Web-службу, возвращающую без всякой обработки присланный запрос:

public class EchoService{

public String getEcho (String req) { return req;

В листинге 4.2 приведено описание этой Web-службы на языке WSDL, использующее протокол SOAP.

Листинг 4.2. Описание Web-службы EchoService

version="1.0" encoding="UTF-8" ?>

targetNamespace="http://echoservice.com/echoservice.wsdl" xmlns="http://www.w3.org/2002/07/wsdl" xmlns:tns="http://echoservice.com/echoservice.wsdl" xmlns:soap="http://www.w3.org/2002/07/wsdl/soapl2" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

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

"http://schemas.xmlsoap.org/soap/encoding/"

namespace= "http: //echoservice. ccm/echcservice .wsdl" use="encoded" />

^oapKbocy enccdingStyle=

"http: //schemas .xmlsoap. org/soap/encoding/" namespace= "http: //echoservice. c^/ech^service .wsdl" use="encoded" />

name="EchoServService">

Binding="tns:EchoServiceSoapBinding" name="EchoService"> location=

"http://localhost:8080/axis/EchoService.jws" />

В листинге 4.2 мы в элементе определили префиксы всех нужных нам пространств имен. Далее мы описали запрос и ответ в двух элементах . Мы дали ИМ имена "getEchoRequest" И "getEchoRe- sponse". В запросе один аргумент типа xsd: string. Этот тип определен в языке XSD. Мы дали аргументу имя req, совпадающее с именем аргумента метода getEcho () . Значению, возвращаемому методом, мы дали имя return, его тип тоже xsd: string.

Имена "getEchoRequest" И "getEchoResponse" ИСПОЛЬЗОВаны В следующем элементе Для указания входных и выходных параметров Web- услуги. В него вложен один элемент . Это означает, что Web- служба предоставляет одну услугу, имя которой "getEcho" совпадает с именем метода, выполняющего эту услугу. В элементе указаны входной и выходной параметры услуги. Затем, элементом мы указали один способ пересылки посланий - SOAP-послания в процедурном стиле, пересылаемые по протоколу HTTP, на что указывает элемент

txarspcrt^=^"ht:tp^://?cheпas^.>пlscap^.c^rc^/?cap^/ht:tp^" />

Если применяется документный стиль SOAP, то в атрибуте style записывается значение "document".

Наконец, в элементе вложенным элементом Связываем элемент с элементом

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

В листинге 4.2 имена с префиксом soap конкретизировали описание послания и способы его пересылки. Посмотрим, какие конкретные протоколы предлагает спецификация WSDL 1.2.

Литература:

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

XSD: определение схемы XML.

XML: расширяемый язык разметки.

WSDL: язык определения веб-сервисов.

Я не собираюсь отвечать технически. Я направляю это объяснение на новичков.

Нелегко общаться между двумя различными приложениями, которые разрабатываются с использованием двух разных технологий. Например, компания в Чикаго может разработать веб-приложение с использованием Java, а другая компания в Нью-Йорке может разработать приложение на С#, и когда эти две компании решили обмениваться информацией, тогда XML появится в картине. Он помогает хранить и транспортировать данные между двумя различными приложениями, которые разрабатываются с использованием разных технологий. Примечание. Это не ограничивается языком программирования, пожалуйста, исследуйте транспортировку информации между двумя различными приложениями.

XSD - это определение схемы. Под этим я имею в виду, что он говорит пользователям разрабатывать свой XML в такой схеме. Пожалуйста, смотрите ниже изображения и внимательно следите за ним с помощью элемента "load-on-startup" и его типа, который является целым числом. В изображении XSD вы можете видеть, что оно предназначено для целочисленного значения для "load-on-startup" и, следовательно, когда пользователь создал свой XML-код, он передал значение int этому конкретному элементу. Напомним, что XSD - это схема и стиль, тогда как XML - это форма для связи с другим приложением или системой. Нужно видеть XSD и создавать XML таким образом, иначе он не будет связываться с другим приложением или системой, которая была разработана с использованием другой технологии. Компания в Чикаго предоставляет шаблон XSD для компании в Техасе, чтобы писать или генерировать свой XML в данном формате XSD. Если компания в Техасе не смогла придерживаться тех правил или схем, упомянутых в XSD, тогда невозможно ожидать правильной информации от компании в Чикаго. После вышеупомянутой истории есть так много всего, что любитель или новичок должен знать, кодируя некоторые вещи, как я сказал выше. Если вы действительно хотите узнать, что будет дальше, тогда лучше посидеть с старшими инженерами программного обеспечения, которые фактически разработали веб-службы. Далее идет WSDL, пожалуйста, следуйте изображениям и попытайтесь выяснить, куда будет вписываться WSDL.

*************** ======== Ниже представлено частичное изображение XML ========== ********* ******

*************** ======== Ниже представлено частичное изображение XSD ========== ********* ******

*************** ======== Ниже представлено частичное изображение WSDL ======= *********** **

Мне пришлось создать образец WSDL для веб-службы под названием "Книга". Обратите внимание, что это XSD, но вы должны назвать его WSDL (язык определения веб-сервисов), потому что он очень специфичен для веб-служб. Ниже WSDL (или, другими словами, XSD) создается для класса Book.java, и он создал службу SOAP. Как создала веб-служба SOAP, это другая тема. Нужно написать класс Java, и перед выполнением его создания в качестве веб-службы пользователь должен убедиться, что Axis2 API установлен, и Tomcat для размещения веб-службы на месте.

В качестве сервис-провайдера (тот, кто позволяет другим (клиентам) получать доступ к информации или данным из своих систем) фактически дает клиенту (тем, кто должен использовать информацию или данные сервис-провайдера) полный доступ к данным через веб-службу, ни одна компания на земле не готова предоставить свою базу данных для посторонних. Как и моя компания, я решил предоставить некоторую информацию о продуктах через веб-службы, поэтому нам пришлось создать шаблон XSD и передать некоторые из наших клиентов, которые хотят работать с нами. Они должны написать код для полного использования данного XSD и сделать вызовы Web Service для извлечения данных из servicer и преобразования данных, возвращенных в их подходящее требование, а затем отображать или публиковать данные или информацию о продукте на своем веб-сайте. Простым примером может служить бронирование авиабилетов FLIGHT. Авиакомпания позволит третьим сторонам использовать данные рейса на своем сайте для продажи билетов. Но опять-таки есть намного больше, просто не позволяя стороннему агентству по авиабилетам продавать билеты, там будут синхронизация и безопасность на месте. Если нет синхронизации, то вероятность 100% более одного клиента может купить тот же авиабилет из разных источников.

Я надеюсь, что эксперты будут способствовать моему ответу. Для новичков или новичков очень сложно понять XML, XSD, а затем работать с веб-службами.