Типы данных WSDL

Все типы данных, входящие в WSDL. унаследованы из спецификации XML Schema. Однако следует обратить внимание на тот факт, что WWW консор­циум, известный также как W3C, определил три версии этой спецификации (1999, 2000 и 2001 гг.). Но, учитывая относительную новизну языка WSDL, обычно опираются на наиболее свежую версию спецификации XML Schema, датированную 2001 годом.

В WSDL-описаниях разработчик может применять как простые типы, так и составные. Но составные типы, как известно, создаются из простых. Поэто­му для начала рассмотрим наиболее часто употребляемые простые типы данных.

1. anyURI. Тип обычно применяется для хранения сетевых идентификаторов URL указывающих на расположение каких-либо ресурсов в Сети. URI являются развитием концепции всем известных стандартных URL и по­зволяют адресовать не только какие-либо конкретные файлы, но и их фрагменты. В языке Visual Basic.NET этот тип распознается как String.

2. boolean. Это. конечно, логический тип, который полностью соответству­ет типу Boolean из Visual Basic.NET. Возможные значения — true и false.

3. byte. Тип предназначен для хранения целых чисел. Как можно понять из его наименования, под хранение одного значения отводится один байт, поэтому значение может располагаться в промежутке от -128 до 127. В Visual Basic.NET соответствует типу integer.

4. date. Тип предназначен для хранения дат. В Visual Basic.NET конверти­руется в тип Date.

5. Date Time. Значения этого типа хранят не только дату, но и время. Так же, как и предыдущий, этот тип в Visual Basic.NET конвертируется в тип

Date.

6. double. Тип предназначен для хранения числовых данных. Для каждого значения отводится по восемь байтов, что позволяет хранить числа доста­точно большого диапазона. В Visual Basic.NET ему соответствует тип

Double.

7. float. Тип предназначен для хранения числовых данных. Для каждого значения отводится по четыре байта. В Visual Basic.NET ему соответству­ет тип Single.

8. int. Тип используется для представления целочисленных значений. Для хранения каждого числа используются четыре байта. В Visual Basic.NET ему соответствует тип Long.

9. language. Тип предназначен для хранения значений, указывающих на язык некоего текстового содержимого. Все возможные значения этого типа описаны в документе RFC 1766. В языке Visual Basic.NET для хра­нения подобных значений не предусмотрено отдельного типа, поэтому они хранятся как тип String. Разработчик сам должен будет обрабаты­вать эти значения.

10. long. Тип также используется для хранения целочисленных значений. Для хранения каждого значения отводится восемь байтов. Соответствен­но, диапазон хранимых чисел простирается от —9 223 372 036 S54 775 808 до 9 223 372 036 854 775 807. В Visual Basic.NET хранятся как данные ти­па Variant.

11. negativeInteger. Тип предназначен для хранения отрицательных цело­численных значений. В Visual Basic.NET хранятся как данные типа

Variant.

12. nonnegativeInteger. Тип предназначен для хранения неотрицательных целочисленных значений, то есть положительных чисел и нулевого зна­чения. В Visual Basic.NET хранятся как данные типа Variant.

13. positiveInteger. Этот тип отличается от предыдущего только тем, что не включает в себя нулевое значение — он предназначен только для положи­тельных целых чисел. Как и предыдущие типы, этот в Visual Basic.NET конвертируется в Variant.

14. short. Это тоже целочисленный тип. Его отличием является то. что для хранения каждого значения отводится два байта. В Visual Basic.NET ему соответствует тип Integer.

15. string. Здесь все понятно. Этот тип предназначен для хранения тексто­вых строк. Он практически идентичен типу String из Visual Basic.NET.

16. time. Этот тип предназначен для хранения значений, указывающих на какое-либо время. В Visual Basic.NET эти значения все равно обрабаты­ваются как Date.

17 unsignedByte. Тип предназначен дня целочисленных значений, как и тип byte, но при этом хранит целые без знаковые числа. В Visual Basic.NET этот тип обрабатывается как обычный Byte.

18 unsignedInt. Как и тип int, этот тип хранит целые числа, отводя для них по четыре байта. Отличие заключается в том, что значения этого типа не имеют знака. В Visual Basic.NET обрабатываются как значения типа

Variant.

19 unsignedLong. Как и тип long, хранит целые числа, отводя дня них по восемь байтов. Отличие заключается в том, что значения этого типа не имеют знака. В Visual Basic.NET обрабатываются как значения типа

Variant.

20 unsignedShort. Как и тип short, хранит целые числа, отводя для них по два байта. Отличие заключается в том, что значения этого типа не имеют знака. В Visual Basic.NET обрабатываются как значения типа Long.

На этом мы заканчиваем рассмотрение простейших типов данных, которые чаше всего используются в документах WSDL. Теперь предстоит рассмотреть способы образования составных типов. Проше всего увидеть структуру этого механизма на несложном примере.

Предположим, нам необходимо создать составной тип, в котором бы хранилась информация о зарегистрированном пользователе сервиса. Мы будем хранить имя и фамилию человека, а также его возраст в годах. Для этого нам потребуются два поля, приспособленные для хранения строк, и одно поле для хранения целочисленного значения. Тогда конструкция объявления составного типа будет выглядеть следующим образом:

< еlement name=" PERSON " >

<xsd:complexType>

<xsd:seguence>

<xsd:element name="firstName" type="xsd:string"/>

<xsd:element name="lastName" type="xsd:string"/>

<xsd:element name="ageInYears" type="xsd:int"/>

</xsd:seguence>

</xsd:complexType>

</element>

Легко заметить, что определение нового типа заключается в теги <element> и </element>. Затем, При помощи тегов <xsd:complexType> и </xsd:complexType>, где префикс xsd указывает на используемое пространство имен XML Schema, определяется, что объявляемый тип будет составным. В объявляющем теге <element> мы также использовали атрибут name, значением которого является наименование создаваемого составного типа. То есть наш объявляемый тип носит наименование PERSON.

Само указание структуры типа должно заключаться в теги <xsd: sequence> и < /xsd:sequence>. Каждая отдельная часть типа объявляется при помощи тега <xsd:element>, у которого используются атрибуты name и type для ука­зания наименования элемента и его типа соответственно. В нашем случае мы объявили два элемента типа string с наименованиями firstName и lastName, соответственно, и один элемент aqeInYears типа int. Как можно видеть, объявление составных типов не является такой уж сложной задачей.

Язык WSDL позволяет объявлять не только отдельные простые и составные типы, но и их массивы, а также перечислимые типы. Для начала рассмот­рим создание перечислимых типов.

Основной особенностью перечислимых типов является наличие четко огра­ниченного и явно объявленного множества значений: все возможные значе­ния, которые может принимать переменная перечислимого типа, объявлены заранее. К перечислимым типам можно отнести перечень наименований дней недели или месяцев в году. Перечислимые типы — это перечни.

Как всегда, для начала рассмотрим простой пример объявления перечисли­мого типа. Так, для создания типа sex, который будет состоять из двух воз­можных значений — Male и Female, требуется использовать следующий фрагмент кода:

<element name="Sex">

<xsd:simpleType>

<xsd:restriction base="xsd:strinq">

<xsd:enumeration value="Male" />

<xsd:enumeration value=”Female" />

</xsd: restriction>

</xsd:simpleType>

</element>

Начало объявления типа, как мы видим, — традиционно. Используется тег <element>, внутри которого и размешается все объявление. Однако следую­щим использован тег <xsd:simpleType>, указывающий, что перечислимые типы не относятся к составным. После этого необходимо указать базовый тип, которому будут соответствовать все значения перечислимого типа. Ес­тественно. значения, входящие в состав объявляемого типа, должны быть однотипными. В нашем случае мы используем значения типа strinq. Для объявления базового типа используется тег <xsd: restriction>. Сам базовый тип указывается в виде значения атрибута base, входящего в состав этого типа. Следует отметить, что тег <xsd: restriction> является не просто объ­являющим тегом, он считается охватывающим тегом, поэтому разработчику необходимо использовать закрывающий близнец </xsd: restriction> и раз­мещать перечисление возможных значений в промежутке между этой парой тегов.

Теперь можно переходить к перечислению всех возможных значений создаваемого типа. Для этого мы используем теги <xsd:enumeration>, в которых присутствует атрибут value. Значение этого атрибута и является одним из возможных значений перечислимого типа.

Перейдем к объявлению массивов. Вообще, следует признать, что в WSDL массивы объявляются не при помощи стандартного пространства имен XML Schema. Здесь для этих целей используется тип Аrrау, позаимствованный из языка SOAP. Таким образом, для объявления массива следует воспользоваться пространством имен языка SOAP. Вот простой пример объявления целочисленного массива:

<xsd: complexType name="ArrayOfInt">

<xsd:complexContent>

<xsd:restriction base="soapenc:Array">

<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[ ]"/>

</xsd:restriction»

</xsd:compiexContent>

< / xsd: coiripiexType>

Начнем по порядку рассматривать этот фрагмент кода. Мы объявляем тип с наименованием ArrayOfInt. Массивы считаются сложными типами, поэтому для его объявления мы используем тег <xsd: complexTyре >. Так как одна переменная массива содержит все-таки несколько значений, она сама в некотором роде является составной. Поэтому для создания массивов применяется тег <xsd: complexContent>, который и открывает секцию объявления содержимого типа.

После тега <xsd:complexContent> следует указать тип, на основе которого мы создаем свой массив. Как уже говорилось, в языке WSDL для объявления массивов используется пространство имен языка SOAP, и тип массива заимствуется оттуда. Именно поэтому в теге <xsd:restriction> параметр base имеет значение soapenc:Array. Если обратиться к началу листинга 15.1, то мы увидим, что пространство имен soapenc действительно было объявлено, и его реализация расположена но адресу http://schemas.xmlsoap.org/soap/encoding/.

После того как мы объявили, что создаваемый тип будет массивом, необходимо указать, какого именно типа будут элементы массива. Для этого в нашем объявлении использован следующий тег:

<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[ ]"/>

Для нашего комплексного типа указание типа элементов производится через ссылку на элемент arrayType из пространства имен soapenc. Эта ссылка связывает искомый элемент с конструкцией wsdl:аrrауTуре = "xsd:int[ ]”. То есть тип массива мы задаем через одноименный элемент аrrауTуре, но уже принадлежащий пространству имен wsdl, которое также объявляется в начале WSDL-файла. Соответственно, мы используем тип xsd:int с про­ставленными квадратными скобками после его наименования. Эта конст­рукция и создает массив.

Теперь, когда мы знаем, как распознавать определения типов, собранных в разделе WSDL-документа <types>. можно перейти к рассмотрению структу­ры раздела <messaqe>.

Структура элемента <message>

В элементах <messaqe> описывается структура всех входящих и исходящих сообщений Web-сервиса. Если мы обратимся к WSDL-файлу, описывающе­му наш первый сервис, то мы увидим там несколько элементов <messaqe>. Полностью этот блок выглядит так:

<message name="MyDateSoapIn">

<part name="parameters" element="s0:MyDate" />

</message>

<message name="MyDateSoapOu t">

<part name="parameters" element="s0:MyDateResponse" />

</message>

<message name="MyDateHttpGetIn">

<part name="ShowTime" type="s:string" />

</message>

<message name="MyDateHttpGetOut" >

<part name="Body" element="s0:string" />

</message>

<message name="MyDateHttpPostln">

<part name="ShowTime" type="s:string" />

</message>

<message name="MyDateHttpPostOut”>

<part name="Body" eiement="s0:string" />

</message>

Легко заметить, что в этом блоке содержится шесть разделов <messaqe>. Так как наш сервис, как и все стандартные Web-сервисы концепции Micro­soft.NET, поддерживает три способа передачи и получения информации (get, post и SOAP), то можно убедиться, что на каждый метод приходится по два элемента <messaqe>. То есть для каждого метода один элемент опи­сывает входящее сообщение, а второе — исходящее.

Кстати, эту структуру всего раздела можно распознать и по наименовани­ям элементов <messaqe>. Они складываются из наименования функции Web-сервиса (MyDate), метода передачи информации (HttpPost, HttpGet, Soap), и направленности сообщения (In, Out). Теперь рассмотрим структуру стан­дартного элемента <message>. В нашем примере он выглядит следующим образом:

<message name="MyDateSoapIn">

<part name="parameters" element=”s0:MyDate" />

< /message>

В открывающем теге <message> при помощи атрибута name мы указываем наименование сообщения, созданное но образцу, рассмотренному выше. В общем случае совершенно необязательно использовать именно этот алго­ритм образования имени. Можно использовать любой уникальный иденти­фикатор. Но для того чтобы клиентское приложение могло самостоятельно распознавать структуру сервиса по его WSDL-файлу, стоит все-таки при­держиваться этого правила.

Внутри раздела <message> указываются все передаваемые в нем отдельные элементы. Они объявляются при помощи тегов <part>. В этом теге исполь­зуются атрибуты name и element для задания наименования передаваемой переменной и типа ее значения, соответственно. В нашем случае мы описы­ваем входящее сообщение на языке SOAP. Поэтому передается переменная с наименованием parameters, тип которой описан в разделе <types> под именем MyDate.

Однако следует отметить, что два вышеописанных атрибута, входящие в со­став тега <message>, не являются единственными. Помимо них могут ис­пользоваться и другие атрибуты, такие как type для указания типа перемен­ной и иные атрибуты спецификации XML Schema, описывающие тип и ограничения, налагаемые на переменную. Но чаше всего в дополнительных атрибутах нет нужды.

Вернемся к рассматриваемому нами фрагменту кода. Если в разделах <message>, описывающих входящее и исходящее сообщения на языке SOAP, использовались переменные с наименованием parameters, то сообщения, связанные со стандартными методами протокола HTTP, выглядят несколько иначе. Вот типичный пример входящего сообщения, основанного на методе POST:

<message name="MyDateHttpPostIn">

<part name="ShowTime" type="s: string" />

</message>

Как мы помним, вызываемая функция MyDate имеет один параметр с наиме­нованием showTime. Именно он и описывается в теге <part>. При этом для указания типа передаваемого параметра используется пространство имен XML Schema. Теперь обратимся к блоку <message>, который описывает исходящее сообщение. Определение этого сообщения приведено в следующем фрагменте кода:

<message name="MyDateHttpPostOut">

<part name="Body" element="s0:string" />

< /message>

В этом блоке описывается исходящее сообщение, которое возвращает ре­зультат выполнения функции Web-сервиса. Следует обратить внимание, что помимо изменения наименования элемента (и это понятно, потому что воз­вращаемое значение практически никак не связано с переданным парамет­ром), изменено и пространство имен для указания типа возвращаемого зна­чения. Для возвращаемого значения используется внутреннее пространство имен Web-сервиса с общим наименованием s0. Если обратиться к исходно­му коду контракта Web-сервиса, то можно увидеть, что это пространство имен объявлено следующим образом:

xml ns:s0="http://tempuri.org/" targetNamespace="http://tempuri.org/"

Те же самые правила образования блоков <message> справедливы и для со­общений, связанных со стандартным методом GET протокола HTTP.

Каждое объявление сообщения будет связано с портом, описываемым бло­ком <port>. Но прежде чем мы будем рассматривать структуру этих блоков, следует обратить внимание на блоки <portType>, которые как раз и призва­ны задавать структуру портов.

Структура элемента <portType>

Начнем мы как всегда с рассмотрения искомого раздела, приведенного в нашем основном примере. Вот этот фрагмент кода:

<portType name="Service1Soap">

<operation name= "MyDate" >

<input message="s0:MyDateSoapln" />

<output message="s0:MyDateSoapOut" />

</operation>

</portType>

<portType name="Service1HttpGet">

<operation name= "MyDate" >

<input message="s0:MyDateHttpGetln" />

<output message="s0:MyDateHttpGetOut" />

</operation>

</portType>

<portType name="Service1HttpPost">

<operation name= "MyDate">

<input message="s0:MyDateHttpPostln" />

<output message="s0:MyDateHttpPostOut" />

</operation>

</portType>

В этом фрагменте объявлено три блока <portType>. Если обратить внимание на значения атрибутов name, входящих в состав этого тега, то можно увидеть, что все они описывают методы доступа к описываемому Web-сервису. Так, если взять для рассмотрения блок <рогtType>, описывающий доступ к сер­вису при помощи метода post протокола HTTP, то мы увидим следующий фрагмент кода:

<portType name="ServicelHttpPost">

<operation name="MyDate">

<input message="s0:MyDateHttpPostIn" />

<output message="s0:MyDateHttpPostOut" />

</operation>

</portType>

Структура блока < portTуре >, равно как и остальных блоков файла контрак­та, достаточно прозрачна. При помощи тега <operation> задается наимено­вание функции, к которой будет предоставлять доступ какой-либо порт. В нашем случае это функция MyDate. Внутри блока <operation> описывают­ся входящие и исходящие данные при помощи тегов <input> и <output>, соответственно. А входящие и исходящие данные, как мы уже знаем, опи­сываются при помощи сообщений. Что и наблюдается в этом блоке. Вход­ные данные для порта, предоставляющего доступ к функции MyDate при по­мощи метода post, описываются сообщением MyDateHttpPostIn. Это сооб­щение было рассмотрено в предыдущем разделе. Соответственно, выходные данные задаются сообщением MyDateHttpPostOut. При этом все наименова­ния сообщений указаны с применением внутреннего пространства имен s0.

Следует отметить, что бывает несколько основных видов блоков <portTyре >. В нашем случае рассматривались блоки, которые описывают одновременно и входящие, и исходящие сообщения. В терминологии спецификации WSDL такой тип портов называют запрос-ответ (request-response). Но по­мимо этого типа могут встречаться блоки <portType>, описывающие функ­ции, которые поддерживают только входящие или только исходящие дан­ные. Такие функции называют однонаправленными (one-way). Пример описания подобного типа порта приведен в следующем фрагменте кода:

<portType name="mySегviсе">

< opeгation name="MyFunction">

<input message="MyFunctionPostIn"/>

</operation>

</portType >

Этот блок описывает порт, который передает только входные данные.

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

<portType name="Service1HttpPost">

<operation name="MyDate ">

<input message="s0:MyDateHttpPostIn" />

<output message="s0:MyDateHttpPostOut" />

<fault message="s0:MyDateHttpPostFault" />

</operation>

</portType>

Естественно, для того, чтобы применять подобный расширенный вариант объявления типа, следует позаботиться и об объявлении соответствующего дополнительного сообщения. Вообще же, дополнительное сообщение, из­вещающее о возникновении какой-либо ошибки, дублирует концепцию из­вещения об ошибках языка SOAP. Впрочем, в лабораторной работе, посвященной этому языку, мы увидим принцип действия упомянутой концепции.

Теперь следует рассмотреть формат элементов <binding>, часто называемых привязками, которые определяют формат и протокол передачи данных для каждого объявленного типа порта. Об этом речь пойдет в следующем разделе.

Структура элемента <binding>

Как только что было показано в предыдущем разделе, элементы <binding> детально описывают формат данных и протокол их передачи для каждого определенного типа порта. Типы порта, как известно, задаются блоками <portType>. В нашем примере было три подобных блока. Следовательно, в файле контракта должно находиться и три блока <binding>. Так оно и есть. Фрагмент нашего знакомого WSDL-файла с этими блоками выглядит следующим образом:

<binding name="Service1Soap" type="s0:Service1Soap">

<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />

<operation name= "MyDate">

<soap:operation soapAction="http://tempuri.org/MyDate" style="document" />

<input>

<soap:body use="literal" />

</input>

<output>

<soap:body use="literal" />

</output>

</operation>

</binding>

<binding name="Service1HttpGet" type="s0:Service1HttpGet">

<http:binding verb="GET" />

<operation name="MyDate" >

<http:operation location="MyDate" />

<input>

<http:urlEncoded />

</input>

<output>

<mime:mimeXml part="Body" />

</output>

</operation>

</binding>

<binding name="Service1HttpPost" type="s0:Service1HttpPost">

<http:binding verb="POST" />

<operation name="MyDate" >

<http:operation location="MyDate" />

<input>

<mime:content type="application/x-www-form-urlencoded" />

</input>

<output>

<mime:mimeXml part="Body" />

</output>

</operation>

</binding>

Как можно видеть, наименования элементов, объявляющих привязки, сов­падают с наименованиями соответствующих типов портов. Впрочем, это со­вершенно не обязательно, так как помимо наименований привязок, которые сами по себе могут не нести никакой смысловой нагрузки, лишь бы они были уникальными, в объявляющем теге <binding> используется атрибут type, задающий тип искомой привязки. А значением этого атрибута и будет искомый тип соответствующего порта, определенный при помощи внутрен­него пространства имен.

Теперь рассмотрим детально структуру привязки, соответствующую порту, предоставляющему доступ к функциональности Web-сервиса при помощи языка SOAP. Этот фрагмент кода выглядит следующим образом:

<binding name=”Service1Soap" type="s0:ServicelSoap">

<soap:binding transport="http://schemas.xmlsoap.org/soap/http"

style="document" />

< operation name= "MyDate ">

<soap:operation soapAction="http://tempuri.org/MyDate"

style="document" />

<input>

<soap:body use="literal" />

</input>

<output>

<soap:body use="literal" />

</output>

</operation>

</binding>

После объявляющего тега <binding>, в котором при помощи атрибутов name и type задаются наименование привязки и соответствующий тип порта, размещается тег, указывающий протокол, по которому будет происходить обмен информацией с портом. Для SOAP в нашем случае этот тег имеет следующий вид:

<soap:binding transport="http: //schemas. xmlsoap.org/soap/http" style="document" />

Как можно видеть, для объявления протокола используется тег <binding>, объявленный в пространстве имен soap. Естественно, этот тег отличается от начального тега блока привязки. Сам протокол передачи данных указывает­ся при помощи атрибута transport, в качестве значения которого использу­ется объявление HTTP в языке SOAP.

Следует отметить, что для привязок, ориентированных на стандартные ме­тоды get и post протокола HTTP, объявление протокола, как впрочем, и объявления операций, выглядит несколько иначе. Но об этом — чуть позже. Пока же речь идет о привязке, ориентированной на SOAP.

После того как был объявлен протокол передачи данных от сервиса к кли­енту и обратно, следует объявление операции, к которой будет привязывать­ся порт. Объявление операции производится при помощи тега <ореratiоn>. В объявляющем теге <ореration > присутствует атрибут name, значением ко­торого является имя функции, к которой привязывается порт. В нашем слу­чае это, естественно, функция MyDate.

После объявления операции следует указание адреса, по которому произво­дится доступ к функции. В нашем случае, для доступа при помощи SOAP, эта конструкция выглядит следующим образом:

<soap:operation soapAction="http://tempuri.org/MyDate" style= "document" />

После этого остается лишь объявить все входящие и исходящие данные при помощи блоков, задаваемых тегами <input> и <output>, соответственно. В на­шем случае входящие и исходящие данные приведены к одному типу, по­этому и содержимое искомых блоков выглядит абсолютно одинаково:

<soap:body use="literal" />

Теперь рассмотрим структуру блока привязки <binding> для использования стандартных методов get и post протокола HTTP. Для метода post блок объявления привязки выглядит следующим образом:

<binding name="Service1HttpPost" type="s0:ServicelHttpPost">

<http:binding verb="POST" />

< operation name="MyDate">

<http:operation location="/MyDate" />

<input>

<mime:content type="application/x-www-form-urlencoded" />

</input>

<output>

<mime: mimeXml part="Body" />

</output>

</operation>

</binding>

Следует обратить внимание на тег, объявляющий протокол передачи дан­ных:

<http:binding verb="POST" />

То есть, ключевое слово binding употреблено в области действия простран­ства имен http. А наименование используемого метода post передается как значение атрибута verb.

Указание расположения функции, к которой привязывается искомый порт ServicelHttpPost, производится, как и в предыдущем случае, при помощи тега <operation>. Однако он опять задается при помощи пространства имен http, а сам адрес указан в значении атрибута location. При этом указывает­ся не полный адрес, а всего лишь виртуальный каталог.

Следует также обратить внимание, как именно объявляется формат переда­ваемых и принимаемых данных в блоках <output> и <input>:

<mime:mimeXml part="Body" />

Здесь для ссылки на возвращаемый XML-код используется пространство имен mime, также объявленное в самом начале файла контракта.

Итак, мы рассмотрели структуру блоков <binding>, связывающих порядок передачи данных через порты, которые в свою очередь являются точками доступа к функциям Web-сервиса. Однако структуру объявления портов мы еще не рассматривали. Об этом — в следующем разделе.

Структура элемента <port>

Элементы <port> являются частями элемента <servise>. Их структура чрез­вычайно проста для понимания, так как единственное их предназначение указывать адреса для доступа к функциональности Web-сервиса. Таким об­разом, это точки доступа к функциям. Стандартное объявление одного пор­та в рассматриваемом нами файле контракта выглядит следующим образом:

<port name="Service1HttpGet" binding="s0:Service1HttpGet">

<http:address location="http://localhost/MyService/Service1.asmx" />

</port>

В объявляющем теге <port> при помощи параметра name задается наимено­вание порта, а при помощи параметра binding — наименование привязки для этого порта. Внутри блока<port> располагается один тег, указывающий на адрес доступа к функции, с которой этот порт связывает привязка. При этом следует обратить внимание на тот факт, что все три порта, используе­мые в нашем сервисе, указывают на одну и ту же функцию MyDate, следова­тельно, и адрес точки входа, который указывается в виде значения атрибута location, будет дня всех трех портов одинаковым.

Основные правила для декларирования портов достаточно просты. Каждый порт может объявлять только один адрес доступа к функции Web-сервиса, и каждый порт может использовать только одну привязку.

Итак, как мы убедились, правила объявления портов достаточно просты, и теперь настало время перейти к рассмотрению наивысшего во всей иерар­хии контракта элемента — <service>.

Структура элемента <service>

Как мы уже знаем, элемент <service> является основным во всей иерархии компонентов WSDL-файла. Он наименее абстрактен, если можно так выра­зиться. Вся подготовительная работа была уже проведена предыдущими элементами, и осталось лишь описать структуру Web-сервиса в целом.

В рассматриваемом нами WSDL-файле блок <service> выглядит следующим образом:

<service name="Service1">

<port name="Service1Soap" binding="s0:Service1Soap">

<soap:address location="http://Iocalhost/MyService/Service1.asmx"/>

</port>

<port name="Service1HttpGet" binding="s0:Service1HttpGet">

<http:address location="http://localhost/MyService/Service1.asmx"/>

</port>

<port name="Service1HttpPost" binding="s0:Service1HttpPost">

<http:address location="http://Iocalhost/MyService/Service1.asmx"/>

</port>

</service>

Как можно видеть, блок <service> состоит только из портов. И это вполне понятно, так как именно ими и описывается самый верхний уровень абстракции Web-сервиса. Так что, для описания его структуры в целом необходимо лишь перечислить порты. предоставляющие клиентским приложениям доступ ко всем функциям сервиса.

Следует помнить, что в блоке <service> перечисляемые порты не должны ссылаться друг для друга. То есть, исходящая информация какого-либо порта не может напрямую переводиться во входящую информацию для другого порта: вся коммуникация должна быть ориентирована только на клиентские приложения и иные Web-сервисы.

Итак, мы рассмотрели структуру WSDL-файлов, которые описывают функциональность Web-сервисов и правила доступа к его функциям. Теперь нам предстоит познакомиться с языком SOAP, который чаше всего используется для общения с серьезными многофункциональными сервисами.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: