Каталог решений - Вызов операций WS-сервисов SAP из 1С (передача в параметрах Объектов XDTO)

Вызов операций WS-сервисов SAP из 1С (передача в параметрах Объектов XDTO)

Вызов операций WS-сервисов SAP из 1С (передача в параметрах Объектов XDTO)

В наличии

Довелось столкнуться в своей работе с вызовом из 1С веб-сервисов SAP. Если с передачей простых типов (в терминах XDTO — значений XDTO) в параметрах операции веб-сервиса, не возникло никаких проблем, то с передачей объекта XDTO пришлось повозиться. Несмотря на то, что в 1С я его заполнял, в SAP он воспринимался как пустой. В интернет особо много полезной информации не нашел, поэтому выкладываю свои наработки по теме.

Категория:

Описание

Полезной оказалась эта ссылка:

http://j1c.ru/j1c/node/45

Но там было предложено решение использовать внешний прокси адаптер. Т.к. проблем с обратным вызовом веб-сервиса (из SAP вызывался веб-сервис 1с) не возникло, то решил, что вполне можно обойтись без внешнего прокси адаптера, только штатными средствами 1С.

Собственно все решение приводить не буду, приведу основные функции, которые в итоге получились.

Не знаю, как тут оформлять код, поэтому пока функции выложу так:

1. Сначала подготавливаем структуру 1С, которая по реквизитам аналогична структуре объекта XDTO: на верхнем уровне она должна содержать ИмяКлюча, соответствующее ИмениПараметра операции WS-сервиса. Значениями структуры могут быть: Значение / Массив / Структура, где в свою очередь Массив может содержать Значения / Структуры

Массив используется для передачи таблиц (Список XDTO)

2. Получаем объект Прокси фабрики XDTO

… описывать не буду, все стандартно (я использовал динамическую ссылку, скорее всего можно и статическую)

3. Вызываем функцию:

// Функция инициализирует параметры метода WS и вызывает метод WS
//
Функция ВыполнитьОперациюWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметров1С = Неопределено) Экспорт

    Перем СтруктураПараметровОперацииWS;

    СтруктураПараметровОперацииWS = ИнициализироватьСтруктуруПараметровОперацииWS(СтруктураПараметров1С);
    ПолучитьСтруктуруПараметровОперацииWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS);
    ПреобразоватьСтруктуруПараметровОперацииWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS);

    СтрокаПараметровОперацииWS = ПолучитьСтрокуПараметровОперацииWSПоСтруктуре(СтруктураПараметровОперацииWS, "СтруктураПараметровОперацииWS");

    Попытка
        Если СтруктураПараметровОперацииWS.ВозвращаемоеЗначение = Неопределено Тогда
            Выполнить("ПроксиФабрикиXDTO." + ИмяОперацииWS + "(" + СтрокаПараметровОперацииWS + ")");
        Иначе
            Выполнить("СтруктураПараметровОперацииWS.ВозвращаемоеЗначение = ПроксиФабрикиXDTO." + ИмяОперацииWS + "(" + СтрокаПараметровОперацииWS + ")");
        КонецЕсли;
    Исключение
    КонецПопытки;

    СтруктураПараметровОперацииWS.ВозвращаемоеЗначение = ПреобразоватьОбъектXDTOвСтруктуру(СтруктураПараметровОперацииWS.ВозвращаемоеЗначение);
    Если ТипЗнч(СтруктураПараметровОперацииWS.Параметры) = Тип("Структура") Тогда
        Для Каждого Пар Из СтруктураПараметровОперацииWS.Параметры Цикл
            СтруктураПараметровОперацииWS.Параметры.Вставить("Значение", ПреобразоватьОбъектXDTOвСтруктуру(Пар.Значение));
        КонецЦикла;
    КонецЕсли;

    Возврат СтруктураПараметровОперацииWS;

КонецФункции //ВыполнитьОперациюWS

 
// Процедура заполняет структуру параметров WS по структуре параметров 1С
//
// Параметры:
// ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметров1С, СтруктураПараметровОперацииWS
//
Процедура ПолучитьСтруктуруПараметровОперацииWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS)

    Перем ТипОперацииWS;

    ПроверятьПараметр1С = (СтруктураПараметровОперацииWS.Параметры1С <> Неопределено);

    Для каждого ОперацияWS Из ПроксиФабрикиXDTO.ТочкаПодключения.Интерфейс.Операции Цикл

        Если ОперацияWS.Имя = ИмяОперацииWS Тогда

            Если ОперацияWS.ВозвращаемоеЗначение <> Неопределено Тогда
                СтруктураПараметровОперацииWS.ВозвращаемоеЗначение = ПроксиФабрикиXDTO.ФабрикаXDTO.Создать(ОперацияWS.ВозвращаемоеЗначение.Тип);
            КонецЕсли;

            // Добавим URIПространстваИмен и Объект типа операции
            Для каждого ПакетXDTO ИЗ ПроксиФабрикиXDTO.ФабрикаXDTO.Пакеты Цикл
                Для каждого СвойствоXDTO Из ПакетXDTO.КорневыеСвойства Цикл
                    Если СвойствоXDTO.Имя = ИмяОперацииWS Тогда
                        СтруктураПараметровОперацииWS.URIПространстваИмен = ПакетXDTO.URIПространстваИмен;
                        ТипОперацииWS = СвойствоXDTO.Тип;
                    КонецЕсли;
                КонецЦикла;
            КонецЦикла;

            ОбъектXDTO = ПроксиФабрикиXDTO.ФабрикаXDTO.Создать(ТипОперацииWS);
            Для каждого ПараметрОперацииWS Из ОперацияWS.Параметры Цикл

                Объект1С = Неопределено;
                Если ПроверятьПараметр1С И СтруктураПараметровОперацииWS.Параметры1С.Свойство(ПараметрОперацииWS.Имя, Объект1С) Тогда
                    ОбъектПараметраОперацииWS = ПолучитьОбъектXDTOпоСтруктуреОбъекта1С(ПроксиФабрикиXDTO, ПараметрОперацииWS.Тип, Объект1С);
                    ОбъектXDTO[ПараметрОперацииWS.Имя] = ОбъектПараметраОперацииWS;
                    СтруктураПараметровОперацииWS.Параметры.Вставить(ПараметрОперацииWS.Имя, ОбъектПараметраОперацииWS);
                Иначе
                    СтруктураПараметровОперацииWS.Параметры.Вставить(ПараметрОперацииWS.Имя, Неопределено);
                КонецЕсли;

            КонецЦикла;
            //СтруктураПараметровОперацииWS.ОбъектОперацииWS = ОбъектXDTO;

        КонецЕсли;

    КонецЦикла;

КонецПроцедуры // ЗаполнитьСтруктуруПараметровОперацииWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS)

 
// Процедура Преобразует формат параметров WS 1С в формат WS внешней системы (SAP)
//
// Параметры:
// ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS
//
Процедура ПреобразоватьСтруктуруПараметровОперацииWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS)

    Для каждого ОперацияWS Из ПроксиФабрикиXDTO.ТочкаПодключения.Интерфейс.Операции Цикл

        Если ОперацияWS.Имя = ИмяОперацииWS Тогда

            Для каждого Параметр Из СтруктураПараметровОперацииWS.Параметры Цикл

                ЗаписьXML = Новый ЗаписьXML;
                ЗаписьXML.УстановитьСтроку("UTF-8");
                ЗаписьXML.ЗаписатьОбъявлениеXML();

                ЗаписьXML.ЗаписатьНачалоЭлемента(ИмяОперацииWS);
                ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("", СтруктураПараметровОперацииWS.URIПространстваИмен);

                ПроксиФабрикиXDTO.ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, Параметр.Значение, Параметр.Ключ);

                ЗаписьXML.ЗаписатьКонецЭлемента();

                Стр = ЗаписьXML.Закрыть();

                // Преобразуем XML (для более сложных случаев надо задействовать XSLT)
                Стр = СтрЗаменить(Стр, ИмяОперацииWS, "n0:" + ИмяОперацииWS);
                Стр = СтрЗаменить(Стр, "xmlns=", "xmlns:n0=");

                ЧтениеXML = Новый ЧтениеXML;
                ЧтениеXML.УстановитьСтроку(Стр);
                ЧтениеXML.ПерейтиКСодержимому();
                ЧтениеXML.Прочитать();

                Попытка
                    СтруктураПараметровОперацииWS.Параметры.Вставить(Параметр.Ключ, ПроксиФабрикиXDTO.ФабрикаXDTO.ПрочитатьXML(ЧтениеXML));
                Исключение
                    Сообщить(ОписаниеОшибки());
                КонецПопытки;

            КонецЦикла;

        КонецЕсли;

    КонецЦикла;

КонецПроцедуры // ПреобразоватьСтруктуруПараметровОперацииWS(ПроксиФабрикиXDTO, ИмяОперацииWS, СтруктураПараметровОперацииWS)

 
// Функция возвращает строку параметров через запятую из структуры
//
// Параметры:
// Нет
//
Функция ПолучитьСтрокуПараметровОперацииWSПоСтруктуре(СтруктураПараметровОперацииWS, ИмяПеременнойСтруктурыПараметровОперацииWS)

    Перем ВозвращаемоеЗнач;

    ВозвращаемоеЗнач = "";
    Если ТипЗнч(СтруктураПараметровОперацииWS) = Тип("Структура") Тогда
        Для каждого Пар Из СтруктураПараметровОперацииWS.Параметры Цикл
            ВозвращаемоеЗнач = ВозвращаемоеЗнач + ", " + ИмяПеременнойСтруктурыПараметровОперацииWS + ".Параметры." + Пар.Ключ;
        КонецЦикла;
        Если ВозвращаемоеЗнач <> "" Тогда
            ВозвращаемоеЗнач = Сред(ВозвращаемоеЗнач, 3);
        КонецЕсли;
    КонецЕсли;

    Возврат ВозвращаемоеЗнач;

КонецФункции // ПолучитьСтрокуПараметровОперацииWSПоСтруктуре(СтруктураПараметровОперацииWS, ИмяСтруктурыПараметровОперацииWS)

 
// Функция возвращает структуру по объекту XDTO
//
Функция ПреобразоватьОбъектXDTOвСтруктуру(ОбъектXDTO)

    Перем ВозвращаемоеЗнач;

    Если ОбъектXDTO = Неопределено Тогда

        ВозвращаемоеЗнач = Неопределено;

    ИначеЕсли ТипЗнч(ОбъектXDTO) = Тип("ЗначениеXDTO") Тогда

        ВозвращаемоеЗнач = ОбъектXDTO.Значение;

    ИначеЕсли ТипЗнч(ОбъектXDTO) = Тип("ОбъектXDTO") Тогда

        ВозвращаемоеЗнач = Новый Структура;

        Для каждого СвойствоXDTO Из ОбъектXDTO.Свойства() Цикл

            ВозвращаемоеЗнач.Вставить(СвойствоXDTO.Имя);

            Попытка // свойство - списокXDTO

                СписокXDTO = ОбъектXDTO.ПолучитьСписок(СвойствоXDTO);
                КоличествоСписка = СписокXDTO.Количество();

                МассивЗначений = Новый Массив;
                Для Сч = 0 По КоличествоСписка - 1 Цикл
                    МассивЗначений.Добавить(ПреобразоватьОбъектXDTOвСтруктуру(СписокXDTO.ПолучитьXDTO(Сч)));
                КонецЦикла;

                ВозвращаемоеЗнач[СвойствоXDTO.Имя] = МассивЗначений;

            Исключение // свойство - объектXDTO/значениеXDTO

                ВозвращаемоеЗнач[СвойствоXDTO.Имя] = ПреобразоватьОбъектXDTOвСтруктуру(ОбъектXDTO.ПолучитьXDTO(СвойствоXDTO));

            КонецПопытки;

        КонецЦикла;

    КонецЕсли;

    Возврат ВозвращаемоеЗнач;

КонецФункции

4. Ключевой является преобразование функция ПреобразоватьСтруктуруПараметровОперацииWS

Я ее реализовал простой СтрЗаменить, т.к. этого оказалось достаточно, но в принципе можно было бы провести XSLT- преобразование (в 1С эта возможность тоже штатная). 

Причина возникновения этой функции в том, что 1С добавляет и в узел, и в его подчиненные элементы префикс имени (не знаю, точно ли передаю термины, т.к. не силен в веб технологиях, надеюсь смысл понятен). А SAP эти префиксы не воспринимает, и потому считает соответствующие значение пустыми. Фактические же префикс надо добавлять только в сам узел (в данном случае узел параметра операции). Это я и делаю с помощью СтрЗаменить.

 

Отвечать и оформлять если что, буду позже, просто думаю, что данный материал может пригодится не только для вызова сервисов SAP, но и для других Web-сервисов.

has been added to your cart:
Оформление заказа