При необходимости организовать регулярный или разовый обмен данными между базами 1С, программисты часто сталкиваются с вопросом выбора оптимального механизма. Веб-сервисы (SOAP) являются классическим и надежным инструментом для этой задачи. В этой статье мы подробно разберем, как передать все реквизиты справочника, какие форматы данных использовать и как избежать типичных ошибок при публикации и тестировании сервиса.
Прежде всего, давайте осознаем важную концепцию: веб-сервис — это всего лишь "транспорт". Рассмотрим ситуацию, когда нам нужно передать объект СправочникОбъект. Веб-сервису, по большому счету, все равно, что именно "летит" внутри его параметров. Вы можете передать как жестко структурированный объект XDTO, так и простую строку String, содержащую данные в формате XML или JSON.
Если мы выберем передачу через строку, нам не нужно описывать каждый реквизит справочника в пакете XDTO. Мы можем собрать данные на стороне отправителя, упаковать их в текстовый формат и передать одним параметром. На стороне приемника мы просто распарсим эту строку и запишем данные в базу.
Это наиболее "правильный" и технологичный способ для среды 1С. Вместо того чтобы вручную создавать свойства для каждого реквизита (Наименование, Код, Родитель и т.д.) в дереве объектов веб-сервиса, мы воспользуемся встроенным механизмом СериализаторXDTO. Рассмотрим, как это работает.
Проанализируем процесс: система 1С уже имеет описание всех ваших справочников в метаданных. СериализаторXDTO позволяет преобразовать объект справочника в объект XDTO (и обратно) одной строкой кода. Это избавляет от рутины и минимизирует ошибки при изменении состава реквизитов справочника.
Пример кода на стороне отправителя (вызов веб-сервиса):
// Получаем объект справочника
ОбъектСпр = Справочники.Номенклатура.НайтиПоКоду("00001").ПолучитьОбъект();
// Сериализуем объект в XDTO
ДанныеXDTO = СериализаторXDTO.ЗаписатьXDTO(ОбъектСпр);
// Отправляем данные через прокси веб-сервиса
Прокси.ВыполнитьЗагрузку(ДанныеXDTO);
Если вы хотите сделать обмен более легким или планируете в будущем подключать к обмену внешние системы (не на базе 1С), использование JSON будет отличным решением. Выясним, как реализовать этот подход. Мы можем превратить структуру или таблицу значений с данными справочника в строку JSON и передать её как обычный текст.
Разберем пример формирования такой строки:
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("Код", ОбъектСпр.Код);
СтруктураДанных.Вставить("Наименование", ОбъектСпр.Наименование);
СтруктураДанных.Вставить("Артикул", ОбъектСпр.Артикул);
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
СтрокаДляОтправки = ЗаписьJSON.Закрыть();
Важный момент: При постоянном обмене данными крайне рекомендуется передавать УникальныйИдентификатор (GUID) объекта. Это позволит на стороне приемника найти именно тот же самый элемент, а не создавать дубли по наименованию или коду.
Рассмотрим ситуацию, когда в справочнике тысячи записей. Попытка передать всё одним огромным куском через один вызов метода веб-сервиса может привести к ошибке Timeout (превышение времени ожидания) или нехватке памяти на сервере. Проанализируем способы решения этой проблемы:
НомерСтраницы и РазмерСтраницы.ЗаписьZipФайла. Сжатый двоичный файл затем преобразуется в формат Base64 и передается как строка. Это может уменьшить объем трафика в 5–10 раз.Часто начинающие разработчики сталкиваются с ошибкой "Имя сервиса не задано" при попытке проверить сервис через браузер. Выясним причину этой ситуации. Ошибка обычно возникает из-за неправильного формирования URL или ошибок в файле конфигурации публикации default.vrd.
Посмотрим на структуру правильной ссылки для проверки SOAP-сервиса:
http://ИмяСервера/ИмяПубликации/ws/ИмяВебСервиса?wsdl
Обратите внимание на следующие нюансы:
?wsdl, чтобы браузер мог получить описание сервиса в формате XML.default.vrd в каталоге публикации на веб-сервере (IIS или Apache). В нем должна быть секция <ws>, где указано имя вашего сервиса, точно совпадающее с именем в конфигураторе 1С.NomenclatureTransfer в ссылке написано так же, как в метаданных.Когда данные получены, нам нужно их корректно записать. Рассмотрим пример обработки входящей строки JSON:
Функция ВыполнитьЗагрузку(ДанныеСтрокой)
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ДанныеСтрокой);
Данные = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Поиск объекта по ГУИД или коду
СсылкаНаОбъект = Справочники.Номенклатура.НайтиПоКоду(Данные.Код);
Если СсылкаНаОбъект.Пустая() Тогда
ОбъектЗаписи = Справочники.Номенклатура.СоздатьЭлемент();
Иначе
ОбъектЗаписи = СсылкаНаОбъект.ПолучитьОбъект();
КонецЕсли;
ЗаполнитьЗначенияСвойств(ОбъектЗаписи, Данные);
Попытка
ОбъектЗаписи.Записать();
Возврат "ОК";
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;
КонецФункции
Резюмируем: Для переноса справочника через веб-сервис не обязательно вручную прописывать каждое поле в XDTO. Использование СериализаторXDTO или передача данных в формате JSON/XML через строковый параметр — гораздо более гибкие и простые в реализации подходы. Главное — помнить о пакетной передаче данных и контроле уникальности объектов через GUID.