Как реализовать интеграцию через веб-сервисы в 1С и исправить ошибки типизации XDTO

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

Интеграция с внешними системами через SOAP-протокол — это стандартная, но зачастую сложная задача для разработчика 1С. Основные трудности возникают не столько в создании самой WSСсылки, сколько в правильном формировании структуры данных с помощью ФабрикиXDTO. В данной статье мы подробно разберем, как интегрировать 1С с сервисом планирования маршрутов (на примере «Белтрансспутник»), выясним, что скрывается за кастомными общими модулями, и научимся избегать ошибки «Несоответствие типов» при вызове методов веб-сервиса.

Разбираемся с архитектурой примера и общим модулем

Часто в примерах кода от сторонних сервисов можно встретить вызовы функций вроде инВебСервисы.ПолучитьОбъектВебСервиса. Проанализируем ситуацию: если в вашей конфигурации нет такого модуля, значит, это была внутренняя разработка компании-интегратора. Однако это не повод для паники. Проанализировав контекст, мы понимаем, что эта функция является «оберткой» над стандартными методами платформы 1С для работы с XDTO.

Основная задача подобных функций — сократить код создания объекта нужного типа. Вместо того чтобы каждый раз прописывать пространство имен (URI) и искать тип в фабрике, разработчики создают универсальную процедуру. Рассмотрим, как мы можем заменить этот модуль стандартными средствами 1С.

Шаг 1. Инициализация WS-прокси и авторизация

Прежде чем отправлять данные, нам нужно создать объект прокси. Это «мост», через который 1С общается с сервером. Разберем процесс инициализации по шагам:


Процедура ИнициализироватьВебСервис(Сервис, Пользователь = "", Пароль = "")
    // Если прокси уже создан, повторно инициализировать не нужно
    Если Сервис <> Неопределено Тогда 
        Возврат; 
    КонецЕсли;

    Попытка
        // Создаем прокси на основании WS-ссылки, добавленной в конфигурацию
        // "инМаршрутыБТС" - это имя WS-ссылки в дереве метаданных
        Сервис = WSСсылки.инМаршрутыБТС.СоздатьWSПрокси("VrpWebServiceService", "VrpWebServicePort", , 300);
        
        // Устанавливаем учетные данные для Basic-авторизации
        Сервис.Пользователь = Пользователь;
        Сервис.Пароль = Пароль;
    Исключение
        ЗаписьЖурналаРегистрации("Интеграция.Ошибка", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
        ВызватьИсключение "Не удалось подключиться к веб-сервису!";
    КонецПопытки;
КонецПроцедуры

Обратите внимание на параметр таймаута (300 секунд). При передаче больших массивов заказов логистические сервисы могут долго обрабатывать запрос, поэтому стандартных 30 секунд может не хватить.

Шаг 2. Создание объектов XDTO без использования сторонних модулей

Теперь перейдем к главной проблеме: как получить объект customerDataJaxb, который ожидает сервер. Ошибка «Несоответствие типов (параметр номер '1')» возникает, когда вы пытаетесь передать методу объект, созданный не из той фабрики или с неправильным типом. Рассмотрим правильный способ получения типа:

Выясним причину ошибки: использование конструкций вида Сервис.ФабрикаXDTO.Пакеты[2][9] крайне опасно. Если структура WSDL на сервере изменится (добавится новое поле или тип), индексы сместятся, и ваша интеграция «сломается». Правильнее всего обращаться к типу по его имени и URI пространства имен.


// Определяем URI пространства имен (обычно указано в свойствах WS-ссылки)
ПространствоИмен = "http://service.mms.beltranssat.com/"; 

// Получаем тип объекта из фабрики прокси
ТипОбъекта = Сервис.ФабрикаXDTO.Тип(ПространствоИмен, "customerDataJaxb");

// Создаем экземпляр объекта
ОбъектСервисаГеоТочка = Сервис.ФабрикаXDTO.Создать(ТипОбъекта);

Этот код полностью заменяет функцию инВебСервисы.ПолучитьОбъектВебСервиса и делает ваш алгоритм устойчивым к изменениям API.

Шаг 3. Заполнение данных и работа со списками (Goods)

Часто объект веб-сервиса содержит вложенные коллекции (например, список товаров в заказе). В XDTO это описывается как свойства с неограниченным количеством вхождений. Проанализируем, как правильно заполнить такие данные.

Рассмотрим по шагам процесс добавления товаров в точку доставки:

  1. Создаем основной объект (точку доставки).
  2. Заполняем его простые реквизиты (адрес, координаты).
  3. Для каждого товара создаем отдельный XDTO-объект типа good.
  4. Добавляем созданный объект товара в коллекцию goods основного объекта.

// Заполняем основные свойства
ЗаполнитьЗначенияСвойств(ОбъектСервисаГеоТочка, СтрокаДанных);

// Работа со списком товаров
Для Каждого СтрокаТовар Из СтрокаДанных.Товары Цикл
    // Важно! Тип товара также берем из фабрики
    ТипТовара = Сервис.ФабрикаXDTO.Тип(ПространствоИмен, "good");
    ОбъектТовар = Сервис.ФабрикаXDTO.Создать(ТипТовара);
    
    // Заполняем реквизиты товара (артикул, количество, вес)
    ЗаполнитьЗначенияСвойств(ОбъектТовар, СтрокаТовар);
    
    // Добавляем в список (свойство goods должно быть описано в XDTO как список)
    ОбъектСервисаГеоТочка.goods.Добавить(ОбъектТовар);
КонецЦикла;

Шаг 4. Вызов методов addPoint и updatePoint (Логика Upsert)

Многие современные API не имеют отдельного метода «Создать или Обновить». Вместо этого используется попытка создания, и если объект с таким ID уже существует, вызывается метод обновления. Разберем, как это реализовать в 1С:


Попытка
    // Пытаемся добавить новую точку
    Сервис.addPoint(ОбъектСервисаГеоТочка);
Исключение
    // Если возникла ошибка (например, точка с таким ID уже есть), пытаемся обновить
    Попытка
        Сервис.updatePoint(ОбъектСервисаГеоТочка);
    Исключение
        // Если и тут ошибка - значит, проблема в данных
        Сообщить("Ошибка при передаче точки " + ОбъектСервисаГеоТочка.id + ": " + ОписаниеОшибки());
    КонецПопытки;
КонецПопытки;

Важные рекомендации по отладке

Если вы продолжаете получать ошибку несоответствия типов, проанализируйте ситуацию с помощью встроенного отладчика 1С. Вычислите выражение Сервис.ФабрикаXDTO.Тип(ПространствоИмен, "customerDataJaxb"). В появившемся окне вы увидите структуру Properties. Убедитесь, что:

Использование прямой работы с ФабрикойXDTO вашего WSПрокси — это наиболее надежный и «чистый» способ реализации интеграции, который не зависит от сторонних модулей и гарантирует правильную передачу типов данных на сторону веб-сервиса.

← На главную