Как сформировать SOAP Envelope с помощью XDTO и отправить запрос в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С:Предприятия со сторонними веб-сервисами часто возникает задача отправить SOAP-запрос. В большинстве случаев платформа берет на себя всю рутину через вызовы WSПрокси, однако в нестандартных сценариях (например, при сложной авторизации WS-Security или необходимости получить точный XML-конверт) разработчику требуется сформировать структуру SOAP Envelope вручную через механизмы XDTO или передать сырой XML через HTTPСоединение.

Разберем типичные ошибки, возникающие при создании объекта Envelope через ФабрикаXDTO, и рассмотрим все рабочие способы отправки SOAP-запросов из 1С.

Причина ошибки при создании Envelope через Фабрику XDTO

Проанализируем распространенную ситуацию: разработчик пытается программно создать SOAP Envelope с помощью глобальной или локальной фабрики XDTO, но получает ошибку о том, что указанный тип не найден.

Выясним основные причины этой ошибки:

  1. Отсутствие схемы SOAP в конфигурации: По умолчанию глобальная ФабрикаXDTO содержит только базовые схемы XML-типов. Схема пространства имен SOAP Envelope (например, http://schemas.xmlsoap.org/soap/envelope/ для версии SOAP 1.1) должна быть предварительно импортирована в дерево метаданных конфигурации или загружена из внешнего файла.
  2. Некорректная передача параметров в конструктор ФабрикиXDTO: Конструктор объекта Новый ФабрикаXDTO() в качестве второго параметра ожидает не отдельный объект ПакетXDTO, а массив пакетов (или набор файлов схем).
  3. Несовпадение версий протокола SOAP: Пространство имен для SOAP 1.1 (http://schemas.xmlsoap.org/soap/envelope/) отличается от SOAP 1.2 (http://www.w3.org/2003/05/soap-envelope). Если схема импортирована для одной версии, а обращение идет к другой, платформа не сможет обнаружить тип.

Способ 1. Импорт XSD-схемы SOAP в конфигурацию и создание объекта через ФабрикуXDTO

Разберем по шагам, как правильно добавить схему SOAP Envelope в конфигурацию и сформировать структуру конверта программно.

  1. В дереве метаданных конфигуратора перейдем к ветке Общие > XDTO-пакеты.
  2. Нажмем правой кнопкой мыши и выберем пункт Импорт XML-схемы.
  3. В диалоговом окне укажем прямой URL-адрес схемы (например, http://schemas.xmlsoap.org/soap/envelope/) либо выберем предварительно сохраненный локальный файл .xsd.
  4. После завершения импорта схема появится в составе конфигурации с соответствующим пространством имен.

Посмотрим на пример кода, позволяющего создать объект Envelope через глобальную фабрику:


URI_SOAP = "http://schemas.xmlsoap.org/soap/envelope/";
EnvelopeXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(URI_SOAP, "Envelope"));
EnvelopeXDTO.Body = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(URI_SOAP, "Body"));

Если мы создаем фабрику динамически на базе внешних файлов схем без добавления в метаданные, используем метод СоздатьФабрикуXDTO():


МассивСхем = Новый Массив;
МассивСхем.Добавить("C:\Schemas\soap-envelope.xsd");
МассивСхем.Добавить("C:\Schemas\service-types.xsd");

Фабрика = СоздатьФабрикуXDTO(МассивСхем);
ТипКонверта = Фабрика.Тип("http://schemas.xmlsoap.org/soap/envelope/", "Envelope");
Конверт = Фабрика.Создать(ТипКонверта);

Способ 2. Штатный вызов веб-сервиса через WSПрокси (рекомендуемый)

Если сервис предоставляет стандартный WSDL-контракт, формировать XML-конверт вручную не требуется. Платформа 1С самостоятельно создает весь Envelope, передает заголовки и преобразует ответ в объекты XDTO.

Рассмотрим типовой пример работы через WSОпределения и WSПрокси:


URL_WSDL = "http://api.service.com/service.wsdl";
Определения = Новый WSОпределения(URL_WSDL, "Логин", "Пароль");

URIПространства = "http://api.service.com/";
ИмяСервиса = "Service";
ИмяТочки = "ServiceSoapPort";

Прокси = Новый WSПрокси(Определения, URIПространства, ИмяСервиса, ИмяТочки);
Прокси.Пользователь = "Логин";
Прокси.Пароль = "Пароль";

// Вызываем метод веб-сервиса напрямую
Ответ = Прокси.GetData(Параметр1);

Способ 3. Формирование XML и отправка через HTTPСоединение

Когда требуется отправить сформированный вручную SOAP XML (например, при нестандартных заголовках безопасности WS-Security или при отсутствии WSDL), используем связку HTTPСоединение и HTTPЗапрос.

Разберем по шагам подготовку и отправку такого запроса:

  1. Формируем текст XML-документа с помощью ЗаписьXML или сериализацией объекта XDTO через Фабрика.ЗаписатьXML().
  2. Указываем корректные заголовки в зависимости от версии протокола:

    Для SOAP 1.1 обязательны заголовки Content-Type: text/xml; charset=utf-8 и SOAPAction: "URI_Действия".

    Для SOAP 1.2 используется Content-Type: application/soap+xml; charset=utf-8; action="URI_Действия" (заголовок SOAPAction не передается).

  3. Выполняем отправку методом ОтправитьДляОбработки().

Посмотрим на пример отправки SOAP 1.1 запроса:


Сервер = "api.service.com";
Ресурс = "/soap-endpoint";

// Создаем защищенное соединение (если HTTPS)
Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Защита);

Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Запрос.Заголовки.Вставить("SOAPAction", """http://api.service.com/GetData""");

ТекстSOAP = 
"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:web=""http://api.service.com/"">
|   <soapenv:Header/>
|   <soapenv:Body>
|      <web:GetDataRequest>
|         <web:Id>12345</web:Id>
|      </web:GetDataRequest>
|   </soapenv:Body>
|</soapenv:Envelope>";

Запрос.УстановитьТелоИзСтроки(ТекстSOAP, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Если Ответ.КодСостояния = 200 Тогда
    ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
    // Обрабатываем полученный XML-ответ
Иначе
    ВызватьИсключение "Ошибка сервиса. Код: " + Ответ.КодСостояния;
КонецЕсли;

Ограничения и важные нюансы

При работе с SOAP в 1С следует помнить о следующих особенностях платформы:

  1. Кэширование WSDL: Платформа кэширует описание WSОпределения. Если структура сервиса на стороне контрагента изменилась, сеанс 1С может выдавать ошибки до перезапуска рабочего процесса сервера или клиентского приложения.
  2. Строгая типизация XDTO: При сериализации объектов XDTO в XML платформа требует строгого соблюдения типов схемы. Если в схеме указано обязательное поле (minOccurs="1"), передача значения Неопределено вызовет исключение при выполнении ЗаписатьXML().
← На главную