dotSITE
Шаблоны проектирования Work in Murano Software. Вопросы/Ответы
новости материалы решения форумы группы настройки/о проекте
Логин/Регистрация
Логин:
Пароль:
Запомнить вас:
Регистрация
Забыли пароль?

Комментарии

SOAP - Simple Object Access Protocol

Simple Object Access Protocol - SOAP

В данной статье рассказывается о протоколе SOAP, что послужит базой для дальнейших статей о SOAP и Webсервисах в платформе Microsoft.NET

Концепции и цели SOAP

На сегодняшний день существует несколько протоколов удаленного взаимодействия приложений. Основными из них являются DCOM (Distributed Component Object Model от Microsoft) и CORBA (Common Object Request Broker Architecture)/ IIOP (Internet Inter-ORB Protocol от Object Managers Group). Эти протоколы обеспечивают взаимодействие приложений, соответствующих определенной объектной модели, с помощью сети. Несмотря на их популярность, ситуация далека от идеала - существует ряд серьезных проблем: во-первых, взаимодействие с использованием вышеуказанных технологий возможно только между приложениями с одинаковой объектной моделью, а в условиях глобальной сети это является сильным ограничением. Во-вторых, использование дополнительных портов для этих протоколов понижает качество защиты сервера, что не приветствуется системными администраторами, и порой они устанавливают firewall на все "не жизненно важные" порты. Таким образом использование указанных протоколов не лучший выход для Интернет, ведь когда вы пишете сетевой сервис, вас интересует, насколько широко он будет использоваться, и возможно ли его взаимодействие с другими независимыми сервисами и приложениями.

Решение этих проблем - SOAP - Simple Object Access Protocol. SOAP обеспечивает взаимодействие распределенных систем, независимо от объектной модели, операционной системы или языка программирования. Он может быть использован для передачи сообщений и для удаленного вызова процедур. Вообще, область его применения не ограничена спецификацией и во многом зависит от реализации. SOAP получен в результате совмещения HTTP и XML, и поэтому имеет ряд существенных преимуществ. Благодаря тому, что он использует протокол HTTP, все возможные неприятности с firewall отсутствуют, так как порт 80 (http) практически всегда открыт. А использование XML представления данных удобно, так как любая современная система программирования имеет API и утилиты для работы с XML данными. К тому же XML обладает очень мощной и расширяемой структурой. Эти особенности обеспечат вашему распределенному приложению возможность очень масштабного применения.

Приведем пример. Допустим вы пишете свой сервис на CORBA, который создает уникальный идентификационный ключ или предоставляет прогноз погоды для всех стран Европы. Раньше клиентам вашего сервиса необходимо было бы иметь объектную модель CORBA. Теперь SOAP дает возможность коммуникации с клиентами, написанными на любом языке с любой объектной моделью и действующими на любой платформе, будь то Perl или Python на Unix, DCOM или CORBA приложение. Вы можете создать действительно децентрализованный независимый широкоиспользуемый сервис.

В разработке SOAP принимало участие множество компаний: DevelopMentor, Microsoft, IBM, UserLand, Iona и несколько других. На данный момент SOAP уже имеет достаточное количество реализаций и обширно используется. SOAP реализован и в Apache сервере, и внедрен в IIS и Windows DNA 2000. Следующие продукты уже поддерживают SOAP: Nouveau ORB (Rogue Wave), Orbix 2000 (CORBA платформа от Iona), Voyager (ObjectSpace), Zope - the Python Application Server (Digital Creations), Frontier groupware product (UserLand), реализации спецификации SOAP для Perl, Java и COM (DevelopMentor). Существует Perl SOAP::Lite модуль.

SOAP - простой протокол, и в нем исключена необходимость полного описания объектной модели. К примеру, вы хотите вызвать удаленную процедуру - вам вовсе не нужно писать большой код для RPC (Remote Procedure Call), соответствующий определенной объектной модели, а вам следует составить SOAP запрос, получив который, удаленный компьютер выполнит процедуру. Вообще, с точки зрения SOAP, имеется всего лишь сторона A и сторона B, и неизвестно кто из них клиент, а кто сервер; неизвестно как и в каком порядке они обмениваются сообщениями. Спецификация SOAP оставляет возможность определять подобные вещи на уровне реализаций, также использование XML в качестве представления данных говорит о том, что вы сможете определять свои тэги, все это говорит о том, что SOAP можно использовать для самых различных целей.

Сам SOAP не несет в себе многих объектных особенностей, таких как, возможность удаленной сборки мусора, контроль версий, конвейерная обработка сообщений, двусторонняя HTTP связь, типовая защищенность, передача "объектов по ссылке" и активация объектов. В действительности, SOAP может быть реализован разработчиком за пару дней с помощью любого языка на любой операционной системе. Реализация необходимых объектных особенностей может находиться в окружении SOAP клиента или сервера, а не в самом протоколе.

SOAP поддерживает HTTP директивы POST и M-POST. Директива M-POST пришла из HTTP Extension Framework, где говорится о том, что новые принудительные (mandatory) HTTP директивы получаются из существующих, добавлением приставки "M-". Сервер, получив запрос, содержащий такую директиву должен действовать по сценарию, зависящему от директивы. Если операция POST не удается (например, блокируется firewall), спецификация SOAP рекомендует повторить попытку с использованием M-POST. Использование директивы M-POST означает, что клиент делает все усилия для успешной передачи сообщения. Это обеспечивает SOAP устойчивость к неудачным выполнениям запроса, и не требует каких либо расширений firewall.

Структура SOAP сообщений

Структура SOAP сообщения очень проста - это XML документ помещенный в HTTP сообщение. SOAP определяет механизм передачи команд и параметров по HTTP вне зависимости от операционной системы, языка программирования, или объектной модели на клиентской или серверной стороне. SOAP основан на существующих интернет технологиях и не требует специальный маршрутизаторов, firewall или proxy серверов. Запросы SOAP содержатся в блоке HTTP POST:

POST /Balances HTTP/1.1
Host: www.abstractbankserver.com
Content-Type: text/xml
Content-Length: nnnn
SOAPMethodName: Some-Namespace-URI#GetCurrentBalance

<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
    <SOAP:Body>
        <m:GetCurrentBalance xmlns:m="Some-Namespace-URI">
                <number>75893</number>
        </m:GetCurrentBalance>
    </SOAP:Body>
</SOAP:Envelope>

Рассмотрим блок поближе: первые четыре строки - стандартные в HTTP POST блоке. Далее следует XML документ: элементы <Envelope> и <Body> реализуют стандартный механизм представления данных; Элемент <GetCurrentBalance> сожержит элемент <number>, в котором находится номер клиентского банковского счета. Смысл этого запроса очевиден: получить баланс на указаном счету.

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

Как вы видите, содержание SOAP запроса, это просто XML Документ, который содержит значения входных параметров метода. Эти элементы представляются в виде порожденных элементов от элемента, который имеет тоже имя и пространство имен, что и метод в директиве SOAPMethodName. В данном примере указано абстрактное пространство имен "Some-Namespace-URI" - в действительности оно заменяется нужным вам пространством имен. Вам следует использовать пространства имен в SOAP сообщениях, чтобы избежать путаницы с тэгами. SOAP сообщение не должно содержать DTD (Document Type Declaration). Ниже приведем пример ответа на запрос:

HTTP/1.1 200 OK
Content-Type: text/xml
Content-Length: nnnn

<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
    <SOAP:Body>
        <m:GetCurrentBalanceResponse xmlns:m="Some-Namespace-URI">
            <return>2600</return>
        </m:GetCurrentBalanceResponse>
    </SOAP:Body>
</SOAP:Envelope>

Первые три строчки - опять же, стандартные для HTTP. XML элемент <GetCurrentBalanceResponse> содержит ответ на запрос о балансе на счету; его порожденный элемент <return> определяет возвращаемое значение.

Теперь опишем структуру XML документа в SOAP сообщении. Корневым элементом документа является <Envelop>. Имя тэга Envelop, в нашем примере, находится в пространстве имен "SOAP" (urn:schemas-xmlsoap-org:soap.v1) - все элементы и атрибуты определенные в SOAP. Далее SOAP Envelop может содержать необязательный элемент <Header>, за которым следует обязательный элемент <Body>. SOAP использует <Header> для предоставления информации, используемой расширениями протокола. Приведем пример использования <Header>:

<soap:Envelope xmlns:soap=‘urn:schemas-xmlsoap-org:soap.v1’>
  <soap:Header>
     <ClientName xmlns="http://www.abstractbankserver.com/clients/">
         <name>John Smith</name>
     </ClientName>
  </soap:Header>
  <soap:Body>
     <m:GetCurrentBalance xmlns:m="Some-Namespace-URI">
         <number>75893</number>
     </m:GetCurrentBalance>
  </soap:Body>
</soap:Envelope>

Получив подобный запрос, сервер может распознать и обработать заголовок, или просто игнорировать его в противном случае. Но дело в том, что бывают случаи, когда заголовок влияет на правильную обработку сообщения, в таких случаях заголовки нельзя просто игнорировать. Подобные элементы заголовка могут быть помечены как принудительные, с помощью атрибута SOAP: mustUnderstand="1". В этом случае заголовок из предыдущего примера будет выглядеть так:

  <soap:Header>
     <ClientName soap:mustUnderstand="1"
	 xmlns="http://www.allabstractbankserverclients.com">
         <name>John Smith</name>
     </ClientName>
  </soap:Header>

SOAP приложение, не распознав принудительный элемент заголовка, должно отклонить сообщение и выдать ошибку. Если сервер не распознает принудительный элемент, он не должен передавать сообщение объекту назначения и должен ответить сообщением об ошибке (fault). Если клиент не распознает принудительный элемент, он должен выдать ошибку времени выполнения. Рассмотрим пример сообщения об ошибке:

 <soap:Envelope  xmlns:soap='urn:schemas-xmlsoap-org:soap.v1'>
  <soap:Body>
    <soap:Fault>
      <faultcode>MustUnderstand</faultcode>
      <faultstring>
        Unrecognized 'ClientName' header
      </faultstring>
	  <runcode>No</runcode>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

Элемент <faultcode> предназначен для определения приложением типа ошибки и должен обязательно присутствовать в сообщении об ошибке SOAP. Сам SOAP определяет небольшой набор кодов ошибок, соответствующих основным ошибкам SOAP:

Код ошибкиЗначение
VersionMismatch или 100 Было обнаружено неверное пространство имен для элемента Envelop
MustUnderstand или 200 Порожденный элемент заголовка, содержащий атрибут mustUnderstand="1", был не распознан
Client или 300 Класс ошибок клиента. Это говорит о том, что сообщение было некорректно сформировано или не содержало достаточно информации для успешного запроса.
Server или 400 Класс ошибок сервера. Это говорит о том, что сообщение не может быть обработано, по причинам не зависящим от контекста. Например, обработка предполагает взаимодействие с процессом или потоком, который не доступен в данный момент. Такое сообщение может быть успешно обработано через некоторое время.

Элемент <faultstring> предназначен для словесного описания ошибки или причин ошибки, он должен присутствовать в сообщение об ошибке. Элемент <runcode> показывет была ли ошибка вызвана SOAP сервером ("No") или приложением на сервере ("Yes"). Также в Fault-сообщении может присутствовать элемент <detail>, который содержит информацию об ошибке, зависимую от приложения. Приведем пример сообщения об ошибке деления на ноль:

<soap:Envelope xmlns:soap=‘urn:schemas-xmlsoap-org:soap.v1’>
  <soap:Body>
    <soap:Fault>
      <faultcode>400</faultcode>
      <faultstring>
        Divide by zero occurred
      </faultstring>
      <detail>
        <t:DivideByZeroException xmlns:t="someURI">
           <expression>x = 2 / 0;<expression>
        </t:DivideByZeroException>
      </detail>
	  <runcode>Yes</runcode>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

Soap и .NET

SOAP, является очень важной частью платформы .NET. Работа Webсервисов основана на SOAP. В платформе существуют все необходимые классы и функции для работы с SOAP. Вы можете написать Webсервис, который с помощью SOAP будет контактировать с приложениями на любой другой платформе. Вообще SOAP очень хорошо вписывается в концепцию "software as a service", и ваше приложение может использовать SOAP запросы как для коммуникации с удаленными приложениями, так и с объектами внутри него самого.

Если вы все еще используете Visual Studio 6.0 - начать работу с SOAP вы можете скачав SOAP Toolkit для Microsoft Visual Studio 6.0.

Эта статья - вступлению к циклу статей и документации по SOAP и Webсервисам в платформе Microsoft.NET. В следующей статье будут подробнее рассмотрены Webсервисы и основные классы платформы .NET для работы с SOAP.



Контакт Реклама на сайте Спонсорам Веб мастерам

Лицензионное соглашение - © 2000-2010 dotSITE
Хостинг .NET предоставлен PARKING.RU
Поддержку сайта осуществляет Murano Software Inc., Offshore software development