Главная » Java, Web, XML » Протокол SOAP и Web Services

0

Как уже говорилось в предыдущей главе, Web-службы обмениваются информацией с клиентами и между собой, посылая сообщения на языке XML. Теги этой реализации XML, правила оформления документа XML и порядок обмена документами определены протоколом SOAP. Протокол SOAP создан в 1998 году командой разработчиков под руководством Дейва Винера (Dave Winer), работавшей в корпорации Microsoft и фирме Userland. Название протокола — "Простой протокол доступа к объектам" — отражает его первоначальное назначение — обращаться к методам удаленных объектов. Назначение протокола изменилось, сейчас это протокол всякого взаимодействия Web-служб и компонентов слабо связанных распределенных приложений. Он уже не совсем прост, да и об объектах он ничего не говорит. Многие разработчики предлагают назвать его "Service Oriented Architecture Protocol", оставив прежнее сокращение. Чтобы прекратить эти попытки, в спецификации SOAP 1.2 указано, что слово "SOAP" отныне никак не будет расшифровываться.

В конце 1999 года разработка протокола была передана в консорциум W3C (http: //www.w3.org/).

В мае 2000 года консорциум выпустил свою версию SOAP 1.1. Послание, написанное по протоколу SOAP, оформляется документом XML, активно использующим пространства имен. Имена элементов XML версии SOAP 1.1 относятся к пространству имен с идентификатором http://schemas.xmlsoap.org/soap/envelope/.

Черновик второй версии SOAP 1.2 был выпущен в 2001 году, его пространство имен называлось в то время http://www.w3.org/2001/06/soap-envelope.

Заметьте, что именно идентификатор пространства имен, а не номер 1.1 или 1.2 определяет версию SOAP. Сервер не станет рассматривать SOAP- послание и вернет сообщение об ошибке                                    если заметит

несоответствие пространства имен.

В то время как я пишу эти строки, версия SOAP 1.1 остается рабочей. Версия 1.2 никак не может выйти из подготовительной стадии, но уже используется, например, в SOAP::Lite, Apache SOAP 2.3, Apache Axis. Поэтому в этой главе я буду излагать версию 1.2, отмечая ее отличия от версии 1.1.

Спецификация рабочей версии SOAP всегда хранится по адресу http://www.w3.org/TR/SOAP/. Документы, лежащие по этому адресу, заменяются новыми при замене рабочей версии.

Черновая версия SOAP постоянно обновляется, при этом меняется идентификатор пространства имен. Новейший вариант черновой версии на время написания книги хранился по адресу http://www.w3.org/TR/soapl2-partl/, а пространство используемых ею имен называлось http://www.w3.org/2002/06/soap-envelope. Заметьте, что спецификация SOAP 12 состоит из двух частей: part 1 и part2. Вторая часть спецификации — приложение — содержит правила записи сложных типов данных. У спецификации есть еще одна часть partO — примеры посланий, составленных по правилам SOAP 1.2.

Структура SOAP-послания

Спецификация определяет SOAP-послание как документ XML, не содержащий объявление типа документа и инструкций по обработке. Корневой элемент этого документа XML называется <Envelope>. У элемента могут быть атрибуты   определяющие пространства имен,

и другие атрибуты, снабженные префиксами. В корневой элемент вкладывается один необязательный элемент   содержащий заголовок послания, и один обязательный элемент <Body>, в который записывается содержимое послания. Версия 1.1 позволяла после тела <Body> записать произвольные элементы, их имена обязательно следовало снабжать префиксами. Версия 1.2 запрещает писать что-либо после элемента <Body>. Короче говоря, общая структура SOAP-послания такова:

<?xml version="1.0" ?> <env:Envelope

xmlns:env="http://www.w3.org/2002/06/soap-envelope">

<env:Header>

< ! — Блоки заголовка —> </env:Header>

<env:Body>

<!— Содержимое послания — > </env:Body>

</env:Envelope>

Элемент <Header>, если он есть в послании, записывается первым в теле элемента <Envelope>. Кроме атрибутов xmlns, в нем может быть атрибут actor, указывающий адресом URI конкретный SOAP-сервер, которому предназначено послание.

Дело в том, что SOAP-послание может пройти через несколько SOAP- серверов или через несколько приложений на одном сервере. Эти приложения выполняют предварительную обработку блоков заголовка послания и передают его друг другу. Все эти серверы и/или приложения называются SOAP-узлами (SOAP nodes). Спецификация SOAP не определяет правила прохождения послания по цепочке серверов. Для этого разрабатываются другие протоколы, например, Microsoft WS-Routing.

Атрибут actor задает целевой SOAP-узел — тот, который расположен в конце цепочки и будет обрабатывать заголовок полностью. Значение

атрибута actor показывает, что обрабатывать заголовок будет первый же сервер, получивший Атрибут actor может встречаться в отдельных блоках заголовка, указывая узел- обработчик этого блока. После обработки блок удаляется из SOAP- послания.

В версии 1.2 атрибут actor заменен атрибутом role, потому что в этой версии SOAP каждый узел играет одну или несколько ролей. Спецификация пока определяет три роли SOAP-узла.

?         Роль http://^^.w3.org/2002/06/soap-envelope/role/ultimateReceiver играет конечный, целевой узел, который будет обрабатывать заголовок.

?         Роль http://www.w3.org/2002/06/soap-envelope/role/next играет промежуточный или целевой узел. Такой узел может играть и другие, дополнительные роли.

?         Роль http://www.w3.org/2002/06/soap-envelope/role/none не должен играть ни один SOAP-узел.

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

Значением атрибута role может быть любая строка URI, показывающая роль узла, которому предназначен данный блок заголовка. Значением по умолчанию для этого атрибута служит пустое значение, то есть, просто пара кавычек, или строка URI http://\vw\v.w3.org/2002/06/soap-envelope/rale/ultimateReceiver.

Значение атрибута role показывает, что блок должен быть обработан узлом, играющим роль, определенную такой же строкой.

Еще один атрибут элемента <Header>, называемый urnstUnderstand, принимает значения о или 1. Его значение по умолчанию равно о. Если атрибут mustunderstand равен 1, то SOAP-узел при обработке элемента обязательно должен учитывать его синтаксис, определенный в схеме документа, или совсем не обрабатывать послание. Это повышает точность обработки послания.

В версии SOAP 1.2 вместо цифры о надо писать слово false, а вместо цифры 1 писать слово true.

В тело заголовка <Header> можно вложить произвольные элементы, ранее называвшиеся статьями (entries) заголовка. В версии 1.2 они называются блоками (blocks) заголовка. Их имена обязательно помечаются префиксами. В блоках заголовка могут встретиться атрибуты role или actor и mustunderstand. Их действие будет относиться только к данному блоку. Это позволяет обрабатывать отдельные блоки заголовка промежуточными SOAP- узлами, теми, чья роль совпадает с ролью, указанной атрибутом role. В листинге 3.1 приведен пример такого блока.

Листинг 3.1. Заголовок с одним блоком

<env:Header>

<t:Transaction

xmlns:t="http://some.com/transaction" env:role=

"http://www.w3.org/2002/06/soap-envelope/role/ultimateReceiver" env:mustUnderstand="1">

5

</t:Transaction> </env:Header>

Элементы, вложенные в блоки заголовка, уже не называются блоками. Они не могут содержать атрибуты role, actor И mustunderstand.

Элемент <Body> обязательно записывается сразу за элементом <Header>, если он есть в послании, или первым в SOAP-послании, если заголовок отсутствует. В элемент <Body> можно вложить произвольные элементы, спецификация никак не определяет их структуру. Впрочем, определен один элемент            содержащий сообщение об ошибке.

Сообщение об ошибке <Fault>

Если SOAP-сервер, обрабатывая поступившее к нему SOAP-послание, заметит ошибку, то он прекратит обработку и отправит клиенту SOAP- послание, в тело которого запишет один элемент <Fault> с сообщением об ошибке.

В сообщении, записанном в теле элемента                        версии SOAP 1.1 выде

ляются четыре части, описанные следующими вложенными элементами.

?         Код ошибки <faultcode> — сообщение, показывающее тип ошибки. Оно предназначено для программы, обрабатывающей ошибки.

?         Описание ошибки <faultstring> — словесное описание типа ошибки, предназначенное для человека.

?         Место обнаружения ошибки <faultactor> — адрес URI сервера, заметившего ошибку. Полезно, когда послание проходит цепочку SOAP- узлов, для уточнения природы ошибки. Промежуточные SOAP-узлы обязательно записывают этот элемент, целевой SOAP-сервер не обязан это делать.

?         Детали ошибки <detail> — описывают ошибки, встреченные в теле <Body> послания, но не в его заголовке. Если при обработке тела ошибки не обнаружены, то этот элемент отсутствует.

Например: <env:Envelope

xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body>

<env:Fault>

<faultcode>env:MustUnderstand</faultcode> <faultstring>SOAP Must Understand Error</faultstring> </env:Fault> </env:Body>

</env:Envelope>

Версия SOAP 1.2 изменила содержание элемента                   Как описано в

пространстве имен http://www.w3.org/2002/06/soap-envelope, в него входят два обязательных элемента и три необязательных элемента.

Обязательные элементы.

?         Код ошибки <code>. Он содержит обязательный вложенный элемент <:value> с кодом ошибки и необязательный вложенный элемент <subcode>, содержащий, опять-таки, элемент <value> с уточняющим кодом ошибки и элемент <subcode>, и далее все повторяется рекурсивно.

?         Причина ошибки <Reason>. Содержит необязательный атрибут xml: lang, указывающий язык сообщения (см. главу Г), и произвольное число вложенных элементов с описанием ошибки.

Необязательные элементы.

?           <Node> — адрес URI промежуточного SOAP-узла, заметившего ошибку.

?           <Role> — роль SOAP-узла, заметившего ошибку.

?         <Detail> — описание ошибки, замеченной при обработке тела <Body> послания, но не заголовка.

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

Листинг 3.2. Сообщение об ошибке

<?xml version=’1.0′ ?>

<env:Envelope

xmlns:env="http://www.w3.org/2002/06/soap-envelope" xmlns:rpc=’http://www.w3.org/2002/06/soap-rpc’>

<env:Body>

<env:Fault>

<env:Code>

<env:Value>env:Sender</env:Value>

<env:Subcode>

<env:Value>rpc:BadArgumentsc/env:Value> </env:Subcode>

</env:Code>

<env:Reason>Ptocessing ETror</env:Reason> <env:Detail>

<e rmyfaultdetails

xmlns:e="http://www.example.org/faults"> <message>№me does not match</message> <errorcode>999</errorcode> </e:myfaultdetails> </env:Detail> </env:Fault> </env:BccУ>

</env: Envelope>

Типы ошибок

Список кодов ошибок постоянно меняется и расширяется. Версия 1.1 определяет четыре типа ошибок.

•        versionMismatch — пространство имен неопознано. Может быть, оно устарело или его имя написано неправильно.

? MustUnderstand — блок заголовка, помеченный атрибутом mustUnderstand со значением 1, не отвечает своему синтаксису, определенному в схеме документа.

?         client — документ XML, содержащий послание, неправильно сформирован и по этой причине сервер не может его обработать. Клиенту следует изменить послание.

•Server — сервер не может обработать правильно записанное послание по своим внутренним причинам.

Версия 1.2 определяет пять типов ошибок.

? VersionMismatch — пространство имен неопознано. Может быть, оно устарело или его название написано неправильно, или в послании встретилось имя элемента XML, не определенное в этом пространстве имен. В заголовок ответа сервер записывает элемент <upgrade>, перечисляющий вложенными элементами <envelope> правильные названия пространств имен, понимаемые сервером. Ответ сервера показан в листинге 3.3.

?        MustUnderstand — блок заголовка, помеченный атрибутом mustunderstand со значением true, не отвечает своему синтаксису, определенному в схеме документа. Сервер записывает в заголовок ответа элементы <Misunderstood>, атрибут qname которых содержит имя неправильного блока. Листинг 3.4 содержит пример ответа, который будет сделан сервером, если заголовок листинга 3.1 окажется неправильно записанным.

?         DataEncodingUnknown — в послании встретились непонятные данные, может быть, они записаны в неизвестной кодировке.

•Sender — документ XML, содержащий послание, неправильно сформирован и по этой причине сервер не может его обработать. Клиенту следует изменить послание.

?         Receiver — сервер не может обработать правильно записанное послание по своим внутренним причинам, например, отсутствует нужный XML- парсер.

Сервер может добавить к этим типам ошибок какие-то свои типы. Обычно

они детализируют стандартные типы, и сообщения о них появляются в элементах <subcode>, как было показано выше в листинге 3.2.

? Листинг 3.3. Ответ сервера с сообщением об ошибке типа VersionMismatch

<?xml version="1.0" ?> <env:Envelope

xmlns:env="http://www.w3.org/2002/06/soap-envelope">

<env:Header> <upg:Upgrade

xmlns:upg="http://www.w3.org/2002/06/soap-upgrade">

<envelope qname="nsl: Envelope"

xmlns:nsl="http://www.w3.org/2002/06/soap-envelope"/>

<envelope qname="ns2: Envelope"

xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"/> </upg:Upgrade> </env:Heacl?r> <env:Body> • <env:Fault>

<env:Code>

<env:Value>env:VersionMismatch</env:Value>

</env:Cocle>

<env: Reason>Version Mismatch</env: Reason>

</env:Fault> </env:Bocy> </env:Envelope>

ЛистонгЗ.4. Ответ сервера с сообщением об ошибке типа MustUnderstand

<?xml version="1.0" ?>

<env:Envelope xmlns:env=’http://www.w3.org/2002/06/soap-envelope’ xmlns:flt=’http://www.w3.org/2002/06/soap-faults’ >

<env:Header>

<fIt:Misunderstood qname=’t:Transaction’

xmlns:t=’http://some.com/transaction’ />

</env:Header>

<env:Body>

<env:Fault> <env:Code>

<env:Value>env:MustUnderstand</env:Value>

</env:Code>

<env:Reason>

One or more mandatory headers not understood </env:Reason>

</env:Fault>

</env:Body>

</env:Envelope>

Литература:

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

По теме:

  • Комментарии