Формы сообщений

Спецификация SOAP старше WSDL. На момент ее разработки и утверждения у программистов не было механизмов описания Web-сервисов, которые можно было бы использовать без предварительного изучения протокола. Для обхода этой проблемы спецификация SOAP определяет специальный формат обмена сообщениями, известный как RPC/encoded. RPC – определяет форму сообщения, а encoded – методы сериализации данных в тело SOAP-сообщения. Encoded сериализация подробно описана в разделе 5 спецификации [6].

С выходом WSDL появилась возможность описывать формат сообщений с помощью XML Schema. Эта форма получила название document/literal. Document означает, что тело SOAP-сообщения может и не представлять собой вызов метода. Это может быть просто набор элементов, соответствующих какому-либо бизнес-документу. Literal означает, что формат сообщения полностью определяется секцией types, т.е. схемой документа. Никаких особых правил, как в случае encoded сериализации, здесь не применяется.

Возможны также и комбинации этих форматов: RPC/literal, document/encoded. Рассмотрим их по порядку.

RPC-стиль подразумевает, что сообщение содержит только один элемент верхнего уровня (непосредственный дочерний элемент SOAP:Body), название которого соответствует имени удаленного метода. Имя метода определяется именем элемента operation секции portType WSDL-документа. Пространство имен этого элемента определяется значением атрибута namespace элемента связывания SOAP:Body. Каждый вложенный в него элемент представляет параметр метода, имя которого определяется именем части в секции message WSDL-документа. Таким образом, частей может быть несколько, так как их количество равно количеству параметров метода. Элемент, представляющий параметр, должен быть неквалифицированным, т.е. не должен принадлежать никакому или пустому пространству имен. Содержимое элементов, представляющих параметры, определяется типом сериализации: encoded или literal.

Document стиль определяет, что сообщение будет в точности соответствовать схеме, описанной в разделе types. Количество элементов верхнего уровня может быть любым. Имя элемента верхнего уровня определяется схемой, а не именем операции, как в RPC-стиле. Количество частей, ссылающихся на тип в разделе message – не более одной. Если часть ссылается на элемент, их может быть несколько. Содержимое элементов, представляющих параметры, определяется типом сериализации: encoded или literal.

Encoded-сериализация слишком сложна и объемна для этой статьи. Интересующихся отсылаю к разделу 5 спецификации [6]. Что касается WSDL-документа, то используя этот тип сериализации, вы не можете указывать конкретных элементов в части секции message. Т.е. допустим только синтаксис указания типа.

Эквивалент функции void foo(int i);- RPC/encoded

<message name="fooIn"> <part name="i" type="xsd:int" /></message><message name="fooOut" /><portType name="Port1"> <operation name="foo"> <input message="fooIn" /> <output message="fooOut" /> </operation></portType>

Тело SOAP сообщения

<SOAP-ENV:Body> <m:foo xmlns:m="(TargetNamespace)" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <i xsi:type="xsd:int">0</i> </m:foo> </SOAP-ENV:Body>

Эквивалент функции void foo(int i);- document/encoded

<message name="fooIn"> <part name="i" type="xsd:int"/></message><message name="fooOut"/><portType name="Port1"> <operation name="foo"> <input message="fooIn" /> <output message="fooOut" /> </operation></portType>

Тело SOAP-сообщения

<SOAP-ENV:Body> <SOAP- ENC:int>0</SOAP- ENC:int > </SOAP-ENV:Body>

Literal-сериализация намного проще encoded, так как содержимое документа определяется только схемой. Части сообщения могут быть представлены либо одним типом, либо набором элементов. В первом случае, само содержимое элемента soap:body кодируется в соответствии с типом части, а во втором случае – тело SOAP-сообщения содержит набор описанных элементов.

Эквивалент функции bool foo(string s,int i); - RPC/literal

<s:schema> <s:element name="str" type="xsd:string"/> <s:element name="int" type="xsd:int"/></s:schema><message name="fooIn"> <part name="s" element="m:str" /> <part name="i" element="m:int" /></message><message name="fooOut"> <part name="retval" type="xsd:boolean" /> </message><portType name="Port1"> <operation name="foo"> <input message="fooIn" /> <output message="fooOut" /> </operation></portType>

Тело SOAP сообщения

<SOAP-ENV:Body> <m:foo xmlns:m="(TargetNamespace)"> <m:str>some string</m:str> <m:int>0</m:int> </m:foo></SOAP-ENV:Body>

Эквивалент функции bool foo(string s,int i); - document/literal с использованием элементов

<s:schema> <s:element name="some_document"> <s:complexType name="unimportant"> <s:sequence> <s:element name="str" type="xsd:string"/> <s:element name="int" type="xsd:int"/> </s:sequence> </s:complexType> </s:element></s:schema><message name="fooIn"> <part name=" unimportant " element="m:some_document" /></message><message name="fooOut"> <part name="retval" type="xsd:boolean" /> </message><portType name="Port1"> <operation name="foo"> <input message="fooIn" /> <output message="fooOut" /> </operation></portType>

Тело SOAP-сообщения

<SOAP-ENV:Body> <m:some_document> <m:str>some string</m:str> <m:int>0</m:int> </m:some_document></SOAP-ENV:Body>

Эквивалент функции bool foo(string s,int i); - document/literal с использованием типа

<s:schema> <s:complexType name="unimportant"> <s:sequence> <s:element name="str" type="xsd:string"/> <s:element name="int" type="xsd:int"/> </s:sequence> </s:complexType></s:schema><message name="fooIn"> <part name="unimportant" type="m:unimportant" /></message><message name="fooOut"> <part name="retval" type="xsd:boolean" /> </message><portType name="Port1"> <operation name="foo"> <input message="fooIn" /> <output message="fooOut" /> </operation></portType>

Тело SOAP-сообщения

<SOAP-ENV:Body> <m:str>some string</m:str> <m:int>0</m:int></SOAP-ENV:Body>

Стили и способы сериализации задаются в секции binding WSDL-документа (см. ниже).

Стиль document/literal постепенно вытесняет остальные стили, так как он намного проще в понимании и реализации. Кроме этого, этот стиль позволяет точно определить содержимое документа по его схеме, тогда как при использовании стиля RPC/encoded нужно знать некоторые правила сериализации.

ПРИМЕЧАНИЕ В новой спецификации SOAP 1.2, которая уже стала рекомендацией, правила RPC-сериализации несколько упрощены, однако они все равно уступают литеральной сериализации по простоте.

Visual Studio.NET для проекта ASP.NET Web-service по умолчанию генерирует именно стиль document/literal, а.Net Remоting придерживается, наоборот, RPC/encoded. В конечном счете, и там и там можно настроить стиль под собственные нужды, так что выбор остается за вами.


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



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