В процессе разработки интеграций часто возникает задача вызвать сторонний веб-сервис (например, написанный на Java или .NET) из среды 1С:Предприятие 8.3. Основная сложность обычно заключается не в самом вызове, а в правильной передаче структуры XML-данных и заполнении HTTP-заголовков для авторизации или передачи метаданных. Разберем основные подходы к решению этой задачи, от стандартных механизмов платформы до гибкого формирования SOAP-запросов вручную.
Это «штатный» способ работы с веб-сервисами в 1С. Если у вас есть адрес WSDL, платформа может автоматически создать описание типов и методов сервиса. Рассмотрим процесс интеграции по шагам.
WSDL. Платформа импортирует схему сервиса.WSПрокси.Проанализируем пример кода для инициализации соединения:
// Определяем параметры подключения
ВебСервисАдрес = "http://myservice.com/corews?wsdl";
ПространствоИмен = "http://namespacelink/";
ИмяСервиса = "CoreWebServiceImplService";
ТочкаПодключения = "CoreWebServiceImplPort";
// Создаем определение и прокси
Попытка
Определения = Новый WSОпределения(ВебСервисАдрес, "Логин", "Пароль");
Прокси = Новый WSПрокси(Определения, ПространствоИмен, ИмяСервиса, ТочкаПодключения);
Прокси.Пользователь = "Логин";
Прокси.Пароль = "Пароль";
Исключение
Сообщить("Ошибка инициализации сервиса: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Важный нюанс: Если сервис требует специфические HTTP-заголовки (как в примере на Java в исходном сообщении), в современных версиях платформы (начиная с 8.3.10) у объекта WSПрокси есть свойство ПользовательскиеЗаголовки. Это соответствие, куда можно добавить любые данные:
Заголовки = Новый Соответствие;
Заголовки.Вставить("Custom-Header", "Value");
Заголовки.Вставить("Username", "MyLogin");
Прокси.ПользовательскиеЗаголовки = Заголовки;
Иногда стандартный WSПрокси не позволяет гибко управлять телом запроса или возникают проблемы с интерпретацией типов данных XDTO. В этом случае мы можем отправить «сырой» SOAP-запрос через HTTPСоединение. Это дает полный контроль над передаваемым XML.
Разберем ситуацию, когда нам нужно передать содержимое XML-файла внутрь тега метода. Выясним причину, по которой простые строки могут не приниматься сервисом: часто это связано со спецсимволами (<, >, &), которые ломают структуру основного XML-конверта.
Рассмотрим пример формирования запроса:
// 1. Формируем тело XML-данных, которые нужно передать
ТекстДляПередачи = " <Data>Содержимое файла</Data> ";
// Чтобы XML не конфликтовал с оберткой SOAP, нужно либо экранировать символы,
// либо обернуть в CDATA. Рассмотрим метод экранирования:
ТекстДляПередачи = СтрЗаменить(ТекстДляПередачи, "&", "&");
ТекстДляПередачи = СтрЗаменить(ТекстДляПередачи, "<", "<");
ТекстДляПередачи = СтрЗаменить(ТекстДляПередачи, ">", ">");
// 2. Собираем полный SOAP-конверт
СтрокаSOAP =
"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:core=""http://namespacelink/"">
| <soapenv:Header/>
| <soapenv:Body>
| <core:createEntities>
| <content>" + ТекстДляПередачи + "</content>
| <batchId>201</batchId>
| <dataType>XML</dataType>
| </core:createEntities>
| </soapenv:Body>
|</soapenv:Envelope>";
// 3. Отправляем запрос через HTTPСоединение
Сервер = "dev-data.service.com";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");
Заголовки.Вставить("SOAPAction", "CreateOperation"); // Если требуется сервисом
Соединение = Новый HTTPСоединение(Сервер, , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос("/corews", Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаSOAP, КодировкаТекста.UTF8);
Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);
Если Ответ.КодСостояния = 200 Тогда
Сообщить("Успешно: " + Ответ.ПолучитьТелоКакСтроку());
Иначе
Сообщить("Ошибка: " + Ответ.КодСостояния);
Сообщить(Ответ.ПолучитьТелоКакСтроку());
КонецЕсли;
Вместо ручной сборки строк (как в примере выше) рекомендуется использовать объект ФабрикаXDTO. Это гарантирует валидность XML и правильное пространство имен. Посмотрим, как создать объект на основе типа из WS-ссылки:
// Получаем тип из фабрики WS-ссылки
ТипКонтента = Прокси.ФабрикаXDTO.Тип("http://namespacelink/", "string");
ОбъектКонтент = Прокси.ФабрикаXDTO.Создать(ТипКонтента, "Ваши данные XML");
// Вызов метода с использованием объектов XDTO
Результат = Прокси.createEntities(ОбъектКонтент, 201, "XML");
Если данные передаются как строка, содержащая XML, 1С может попытаться автоматически экранировать её. Если же сервис ожидает «сырой» XML внутри тега, то параметр в WSDL должен быть описан как anyType или base64Binary.
Проанализируем типичные ошибки при интеграции:
КодировкаТекста.UTF8 и следите за наличием/отсутствием BOM (Byte Order Mark). Большинство современных сервисов ожидают UTF-8 без BOM.УстановитьТелоИзСтроки может вызвать переполнение памяти. В этом случае запишите SOAP-пакет во временный файл и используйте Запрос.УстановитьТелоИзФайла(ПутьКФайлу).ИнтернетПрокси и передать его в конструктор HTTPСоединение.Таким образом, для простых случаев лучше использовать WS-ссылки, так как они типизированы. Для сложных случаев с нестандартными заголовками или специфической структурой пакета оптимальным выбором будет HTTPСоединение с ручным формированием XML через объект ЗаписьXML или ФабрикаXDTO.