Интеграция 1С с системами SAP (особенно через SAP PI/PO) является одной из самых сложных задач для разработчика из-за жестких требований к безопасности, специфических настроек протоколов и нюансов описания WSDL. В этой статье мы подробно разберем, как правильно настроить подключение, почему возникают ошибки «Сервис не найден» или «Порт не найден» и как обрабатывать полученные данные XDTO.
Прежде чем писать код в 1С, нам необходимо детально изучить WSDL-файл (Web Services Description Language). Зачастую SAP-консультанты присылают его отдельным файлом, а не ссылкой. Это статическое определение, которое содержит всю необходимую информацию о структуре сервиса. Разберем, на какие теги нужно обратить внимание в первую очередь, используя Post1С — аналог Postman для отладки запросов.
Внутри WSDL-файла нас интересуют три ключевых параметра, которые мы будем передавать в конструктор WSПрокси:
<wsdl:definitions>.Рассмотрим пример того, как правильно извлекать эти данные. Если вы откроете WSDL в текстовом редакторе или браузере, ищите секцию в самом конце файла:
<wsdl:service name="si_DataLoad_outb_syncService">
<wsdl:port name="HTTPS_Port" binding="p1:si_DataLoad_outb_syncBinding">
<soap:address location="https://sap-server.company.com/MessageServlet?senderService=..." />
</wsdl:port>
</wsdl:service>
Для работы с веб-сервисом в динамическом режиме (без добавления WS-ссылки в конфигурацию) мы используем объекты WSОпределения и WSПрокси. Проанализируем правильный порядок инициализации с использованием программного интерфейса http и учетом использования защищенного соединения SSL.
Сначала подготовим защищенное соединение. Это критично, так как большинство сервисов SAP работают по протоколу HTTPS. Если на сервере используются сертификаты, выданные внутренним удостоверяющим центром компании, их необходимо подключить:
ssl1 = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто),
Новый СертификатыУдостоверяющихЦентровWindows()
);
// Указываем путь к локальному WSDL-файлу и параметры авторизации
Определение = Новый WSОпределения(
"C:/WSDL/sap_service.wsdl",
ЛогинSAP,
ПарольSAP,
,
,
ssl1
);
Если при создании WSПрокси вы получаете ошибку о том, что сервис или порт не найдены, это означает несоответствие переданных строк тем, что указаны в WSDL. Проанализируем типичную ошибку в коде:
// ОШИБКА: часто путают URI пространства имен и имя порта
Прокси = Новый WSПрокси(Определение, "si_DataLoad_outb_syncService", "HTTPS_Port", , , ssl1);
Важно: В конструкторе WSПрокси вторым параметром идет URIПространстваИмен, а не имя сервиса. Правильный вызов должен выглядеть так:
URIПространства = "http://company.com/xi/BC/1C"; // Берем из targetNamespace в WSDL
ИмяСервиса = "si_DataLoad_outb_syncService";
ИмяПорта = "HTTPS_Port";
Прокси = Новый WSПрокси(Определение, URIПространства, ИмяСервиса, ИмяПорта, , ssl1);
Прокси.Пользователь = ЛогинSAP;
Прокси.Пароль = ПарольSAP;
Иногда после успешного создания объекта WSПрокси вызов метода (например, Прокси.GetData()) возвращает ошибку 403 Forbidden. Выясним причину этой ситуации. В системах SAP часто требуется так называемая «Pre-emptive authentication» (предварительная авторизация).
По умолчанию 1С (как и многие другие клиенты) сначала отправляет запрос без заголовка авторизации, ждет ответа 401 Unauthorized, и только потом отправляет данные. Однако настройки безопасности SAP могут быть сконфигурированы так, что любой запрос без авторизации (отличающийся от механики Access и Refresh токенов) сразу обрывается с ошибкой 403.
Если вы столкнулись с такой проблемой, и WSПрокси не помогает, рассмотрим альтернативный вариант — использование HTTPСоединение для ручного формирования SOAP-запроса:
Заголовки = Новый Соответствие();
// Формируем заголовок Basic Auth заранее
СтрокаАвторизации = ЛогинSAP + ":" + ПарольSAP;
Заголовки.Вставить("Authorization", "Basic " + Base64Строка(BinaryDataFromString(СтрокаАвторизации)));
Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");
Заголовки.Вставить("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
Соединение = Новый HTTPСоединение(ИмяСервера, , ЛогинSAP, ПарольSAP, , , ssl1);
Запрос = Новый HTTPЗапрос(ПутьКСервису, Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстSOAPКонверта);
Ответ = Соединение.ОтправитьДляОбъекта(Запрос);
Когда вызов метода прошел успешно, SAP может вернуть сложную структуру ОбъектXDTO. Часто данные упакованы в коллекции или пакеты, и при просмотре ответа кажется, что данных нет или они находятся в «нулевом» элементе.
Разберем, как программно извлечь данные из ОбъектXDTO, если структура заранее неизвестна или является динамической:
Результат = Прокси.MX1(Параметры); // Вызов метода сервиса
// Если результат — это ОбъектXDTO, проанализируем его свойства
Для Каждого Свойство Из Результат.Свойства() Цикл
Значение = Результат.Получить(Свойство);
Если ТипЗнч(Значение) = Тип("СписокXDTO") Тогда
Для Каждого ЭлементСписка Из Значение Цикл
// Обработка элементов коллекции
Сообщить("Найдена запись: " + ЭлементСписка.Имя);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если данные приходят в виде «AnyType» (нетипизированный XML), рассмотрим использование метода Последовательность(). Это позволяет прочитать внутреннее содержимое XML, даже если оно не описано жестко в схеме WSDL.
При обращении к адресу, который заканчивается на /MessageServlet, вы можете увидеть сообщение «Message Servlet is in Status OK». Это системный статус адаптера SAP. Помните, что для вызова конкретной бизнес-логики в URL часто требуется добавлять параметры отправителя и интерфейса:
senderService — техническое имя системы в SAP PI.interface — имя исходящего интерфейса.receiverParty — если используется маршрутизация по участникам.Проанализируем ситуацию: если вы используете локальный WSDL, убедитесь, что в теге <soap:address location="..." /> прописан корректный внешний адрес сервиса. Если там указан внутренний IP-адрес сервера SAP, 1С не сможет до него достучаться из внешней сети, и вам придется вручную переопределять местоположение в конструкторе WSПрокси.
Таким образом, для успешной интеграции необходимо пройти по шагам: проверить валидность WSDL, точно указать URIПространстваИмен, настроить SSL-соединение и при необходимости использовать ручное формирование HTTP-заголовков для прохождения авторизации в SAP.