Вызов веб-сервиса выполнением POST-запроса

Выполнение POST-запроса на примере Yandex.API
Вызов Web-сервиса с помощью динамической ссылки

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

Формирование SOAP-сообщения


Структура SOAP-сообщения выглядит следующим образом:
1. Структура SOAP-сообщения
Заголовок <soap:Header> является необязательным и служит для передачи информации, такой как: аутентификация, информация о защите, информация о транзакция и т.д. Платформа 1С не поддерживает работу с заголовком средствами встроенного языка и так же веб-сервисы, реализованные на этой платформе.

Для самостоятельного формирования SOAP-сообщения необходимо уметь читать WSDL-документ. Документ состоит из пяти элементов, содержащихся под корневым элементом definitions:
  • types - содержит определения схемы для обмена данными между клиентом и сервером. Язык схемы по умолчанию – XMLSchema;
  • message - идентифицирует отдельное сообщение, которым могут обмениваться клиент и сервер. Сообщение состоит из одного или нескольких фрагментов. Каждый фрагмент представляется элементом part и ссылается на элемент или определение типа, заданного внутри элемента types;
  • portType - содержит один или несколько элементов operation. Операцию можно считать соглашением о том, при помощи каких сообщений message клиент и сервер будут взаимодействовать друг с другом;
  • binding - применяется для связывания типа порта с отдельным протоколом с помощью элементов расширения;
  • service - содержит один или несколько элементов port. Элемент port используется для определения адреса web-сервиса, поддерживающего конкретное связывание.
Напишем функцию формирования SOAP-сообщения для сервиса Яндекс.Спеллер:
// Функция формирует SOAP-сообщения для операции checkText.
//
// Параметры
//  Текст  - Строка - текст для проверки орфографии.
//
// Возвращаемое значение:
//   строка   - SOAP-сообщение в формате XML.
//
&НаСервереБезКонтекста
Функция СформироватьСообщениеSOAP(Текст)

МестоположениеWSDL = "http://speller.yandex.net/services/spellservice?WSDL";
WSОпределения = Новый WSОпределения(МестоположениеWSDL);

ПространствоИменSpeller = "http://speller.yandex.net/services/spellservice";
ПакетСпеллер = WSОпределения.ФабрикаXDTO.Пакеты.Получить(ПространствоИменSpeller);
СвойствоXDTO = ПакетСпеллер.КорневыеСвойства.Получить("CheckTextRequest");

checkText = WSОпределения.ФабрикаXDTO.Создать(СвойствоXDTO.Тип);
checkText.Text = Текст;
checkText.lang = "ru";

ПространствоИменSOAP = "http://schemas.xmlsoap.org/soap/envelope/";

ЗаписьXML = Новый ЗаписьXML;
ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8");
ЗаписьXML.УстановитьСтроку(ПараметрыЗаписиXML);
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Envelope", ПространствоИменSOAP);
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("soap", ПространствоИменSOAP);
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xs", "http://www.w3.org/2001/XMLSchema");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ЗаписьXML.ЗаписатьНачалоЭлемента("Body", ПространствоИменSOAP);
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("spel", ПространствоИменSpeller);
WSОпределения.ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, checkText, СвойствоXDTO.ЛокальноеИмя, СвойствоXDTO.URIПространстваИмен);
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.ЗаписатьКонецЭлемента();

Возврат ЗаписьXML.Закрыть();

КонецФункции // СформироватьСообщениеSOAP()


В данной функции с помощью объекта WSОпределения получаются определения веб-сервиса. По пространству имен сервиса Яндекс.Спеллер осуществляется поиск пакета XDTO, для получения типов XDTO, которые описывают входящие/исходящие SOAP-сообщения. Из найденного пакета берется свойство XDTO CheckTextRequest, которое отвечает за входящее сообщение на операцию checkText().
2. Входящее сообщение типа CheckTextRequest операции checkText()
На основании типа свойства XDTO, создается объект XDTO и заполняются свойства этого объекта. Далее происходит формирование SOAP-сообщения, при формировании в тег <soap:Body> помещается объект XDTO (сериализуется в XML). На этом формирование SOAP-сообщения закончено.

Можно поступить более простым способом формирования SOAP-сообщения. Для этого требуется установить программный продукт SoapUI. SoapUI по описанию веб-сервиса для каждой операции генерирует шаблон SOAP-сообщения, в который требуется подставить значения вместо "?". Этот шаблон можно взять за основу и не выполнять формирование SOAP-сообщения объектами встроенного языка.
3. Шаблон SOAP-сообщения в SoapUI
Еще одна полезная информация в SoapUI содержится на вкладке Raw, это HTTP-заголовки, которые необходимы для выполнения вызова веб-сервиса POST-запросом.
4. HTTP-заголовки для вызова веб-сервиса
Конечно, более надежным будет формирование SOAP-сообщения встроенными объектами платформы 1С, так как при каждом вызове веб-сервиса будет получена самая актуальная версия WSDL-документа. SoapUI хороший инструмент, который рекомендую использовать в качестве проверки сформированного SOAP-сообщения да и вообще тестирования веб-сервисов.

Вызов веб-сервиса POST-запросом


Функция вызова веб-сервиса Яндекс.Спеллер HTTP-запросом методом POST:
// Функция осуществляет вызов веб-сервиса проверки правописания POST-запросом.
//
// Параметры
//  ПроверяемыйТекст  - Строка - текст для проверки правописания.
//
// Возвращаемое значение:
//   Строка   - ответ веб-сервиса в формате XML.
//
&НаСервереБезКонтекста
Функция ПроверитьОрфографию(ПроверяемыйТекст)

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");
Заголовки.Вставить("SOAPAction", "http://speller.yandex.net/services/spellservice/checkText");

HTTPЗапрос = Новый HTTPЗапрос("/services/spellservice", Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(СформироватьСообщениеSOAP(ПроверяемыйТекст), "UTF-8");
HTTPСоединение = Новый HTTPСоединение("speller.yandex.net");
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);

Возврат HTTPОтвет.ПолучитьТелоКакСтроку();

КонецФункции // ПроверитьОрфографию()


В данной функции задаются HTTP-заголовки для выполнения POST-запроса:
  • Content-Type - text/xml:charset=UTF-8. Тип передаваемых данных и кодировка;
  • SOAPAction - http://speller.yandex.net/services/spellservice/checkText. Этот заголовок указывает на цель запроса и является обязательным. Каждый веб-сервер может иметь неограниченное количество операций, для этого указывается заголовок SOAPAction чтобы определить какую операцию вызывать.
5. SOAPAction операций веб-сервиса
Далее выполняется сам POST-запрос, подробное описание выполнения этого запроса на платформе 1С описано в статье Выполнение POST-запроса на примере Yandex.API. В ответ веб-сервис возвращает SOAP-сообщение типа CheckTextResponse.
6. Тип исходящего SOAP-сообщения
Плюсом данного метода вызова веб-сервиса является самостоятельный контроль формирования SOAP-сообщения!

Скачать обработку выполнения вызова веб-сервиса POST-запросом можно по этой ссылке.

Полезная литература:
XML-СХЕМА. ЧАСТЬ 0: ПРИМЕР
XDTO - это просто

Комментарии

  1. Великолепно, этим способом наконец то удались связать 1С и SAP
    1С не понимает web-сервисы публикуемые SAP

    ОтветитьУдалить
  2. Спасибо, да, это действительно способ связать 1С и SAP, т.к.
    1С не понимает web-сервисы публикуемые SAP. У меня, в частности, была проблема с WS-Policy. Спасибо!

    ОтветитьУдалить
  3. СПАСИБО за пример!!!
    Очень помог примененный способ в моей разработке.

    ОтветитьУдалить
  4. Еще раз спасибо, благодаря этому примеру заработало

    ОтветитьУдалить
  5. Спасибо тебе, Добрый человек! Двое суток боролся с веб-сервисом, XDTO-пакеты которого не понимает 1С. Благодаря вам решил свою проблему.

    ОтветитьУдалить
  6. Чувак! Респект тебе и уважуха! Только на твоем примере победил обмен 1С с SAP.

    ОтветитьУдалить
  7. Офигенно ! Ты молодец !!!
    Раскрой пожалуйста еще секреты аутентификации, это работает если веб сервис не требует аутентификации, а если требует, то как ему передать имя и пароль ?

    ОтветитьУдалить
    Ответы
    1. Спасибо! Хороший вопрос! Могу предположить, что логин и пароль нужно задавать в соответствующих свойствах объекта HTTPСоединение, времени проверить нету, но начал бы именно с этого.

      Удалить
  8. Спасибо! Помогло в работе с SAP!

    ОтветитьУдалить
  9. Спасибо! Помогло в интеграции с нестандартной шиной, у которой была туча низкоуровневых требований к xml вызова веб-сервиса.

    ОтветитьУдалить

Отправить комментарий