Как передать составные данные и картинки из мобильного приложения 1С на сервер через веб-сервис

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

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

В этой статье мы подробно разберем, как правильно организовать передачу сложных структур данных и графических файлов одной порцией с использованием JSON, XDTO и встроенных функций кодирования платформы 1С.

Анализ проблемы: почему не стоит использовать приведение к строке для бинарных данных

Рассмотрим типичную ошибку при работе с двоичными данными на мобильном клиенте. Попытка перевести двоичные данные (картинку) в строку простым оператором Строка(ДвоичныеДанные) приводит к получению представления байтов в шестнадцатеричном виде (HEX-формат, начинающийся с FF D8 FF E0...).

Такой подход имеет существенные недостатки:

  1. Увеличение объема данных: HEX-представление увеличивает размер передаваемого файла ровно в 2 раза по сравнению с исходными байтами.
  2. Низкая скорость обработки: Сервер потратит значительно больше времени и ресурсов процессора на парсинг и декодирование такой строки.
  3. Ошибки сериализации: При записи объекта в JSON стандартный метод ЗаписатьJSON() вызовет исключение, если ему передать объект типа ДвоичныеДанные напрямую, без предварительного конвертирования в текстовый формат.

Для правильной работы с бинарными файлами в 1С используется кодирование Base64, которое увеличивает объем данных всего на ~33% и корректно поддерживается всеми встроенными механизми платформы.

Решение 1: Передача данных через JSON и Base64

Разберем по шагам создание структуры документа с массивом товаров и массивом картинок для отправки на сервер в формате JSON.

Шаг 1. Подготовка данных и конвертация изображений

Для перевода объекта ДвоичныеДанные в строку формата Base64 воспользуемся глобальной функцией Base64Строка().


// Формируем структуру документа
СтруктураДокумента = Новый Структура;
СтруктураДокумента.Вставить("Номер", ДокументОбъект.Номер);
СтруктураДокумента.Вставить("Дата", ДокументОбъект.Дата);

// Заполняем массив товаров
МассивТоваров = Новый Массив;
Для Каждого СтрИз ТЧТовары Цикл
    СтруктураТовара = Новый Структура;
    СтруктураТовара.Вставить("КодНоменклатуры", СтрИз.Номенклатура.Код);
    СтруктураТовара.Вставить("Количество", СтрИз.Количество);
    МассивТоваров.Добавить(СтруктураТовара);
КонецЦикла;
СтруктураДокумента.Вставить("МассивТоваров", МассивТоваров);

// Заполняем массив фото с кодированием в Base64
МассивКартинок = Новый Массив;
СписокКартинок = ДокументОбъект.Фотографии.Получить(); // Получаем массив или список двоичных данных

Для Каждого СтрФото Из СписокКартинок Цикл
    // СтрФото.Значение содержит объект ДвоичныеДанные
    СтрокаBase64 = Base64Строка(СтрФото.Значение);
    МассивКартинок.Добавить(СтрокаBase64);
КонецЦикла;
СтруктураДокумента.Вставить("МассивКартинок", МассивКартинок);

Шаг 2. Сериализация структуры в JSON-строку

Скомпонованную структуру переводим в JSON-строку с помощью объектов ЗаписьJSON и ЗаписатьJSON:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураДокумента);
СтрокаJSON = ЗаписьJSON.Закрыть();

// Передаем полученную строку в WS-функцию
Результат = Прокси.СохранитьДокументJSON(СтрокаJSON);

Шаг 3. Чтение и декодирование данных на стороне сервера

На сервере принимаем строку JSON, разбираем ее обратно в структуру и декодируем изображения с помощью функции Base64Значение():


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ДанныеДокумента = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

// Обработка картинок
Для Каждого СтрокаBase64 Из ДанныеДокумента.МассивКартинок Цикл
    ДвоичныеДанныеФото = Base64Значение(СтрокаBase64);
    // Сохраняем фото в базу данных или на диск
    // ...
КонецЦикла;

Решение 2: Использование типов XDTO мобильным клиентом

Многие разработчики ошибочно полагают, что если пакет XDTO создан в конфигурации сервера, его нельзя использовать в мобильном приложении без явного копирования структуры пакета в мобильную конфигурацию. Это не так.

При обращении к веб-сервису через объект WSПрокси платформа 1С автоматически считывает WSDL-описание сервиса с сервера и строит локальную фабрику XDTO прямо внутри прокси-объекта.

Разберем, как программно создавать объекты XDTO на мобильном клиенте:


// Подключаемся к веб-сервису
Определение = Новый WSОпределения(URL_WSDL, Логин, Пароль);
Прокси = Новый WSПрокси(Определение, URIПространстваИмен, ИмяСервиса, ИмяПорта);

// Получаем фабрику XDTO, созданную на основе WSDL-описания сервера
Фабрика = Прокси.ФабрикаXDTO;

// Получаем тип XDTO объекта с сервера
ТипДокумента = Фабрика.Тип("http://www.your-company.ru/exchange", "DocumentData");
ОбъектДокумент = Фабрика.Создать(ТипДокумента);

ОбъектДокумент.Number = ДокументОбъект.Номер;
ОбъектДокумент.Date = ДокументОбъект.Дата;

// Заполнение вложенных списков XDTO
ТипТовара = Фабрика.Тип("http://www.your-company.ru/exchange", "ItemData");
Для Каждого СтрИз ТЧТовары Цикл
    ОбъектТовар = Фабрика.Создать(ТипТовара);
    ОбъектТовар.Code = СтрИз.Номенклатура.Код;
    ОбъектТовар.Quantity = СтрИз.Количество;
    ОбъектДокумент.Items.Добавить(ОбъектТовар);
КонецЦикла;

// В свойства с типом xs:base64Binary можно передавать ДвоичныеДанные напрямую!
Для Каждого СтрФото Из СписокКартинок Цикл
    ОбъектДокумент.Pictures.Добавить(СтрФото.Значение); 
КонецЦикла;

// Отправляем сформированный объект XDTO на сервер одной операцией
Результат = Прокси.SaveDocument(ОбъектДокумент);

Важное примечание: Если в XDTO-пакете на сервере для свойства файла указан тип xs:base64Binary, то платформа 1С автоматически выполнит кодирование объекта ДвоичныеДанные в Base64 при отправке SOAP-запроса и декодирование при получении. Явно вызывать Base64Строка() в данном случае не требуется.

Рекомендации по оптимизации обмена фотоматериалами

Проанализируем дополнительные способы оптимизации передачи графических данных с мобильных устройств:

  1. Предварительное сжатие снимков: Камеры современных мобильных устройств делают фотографии размером от 5 до 15 Мегабайт. Передача таких объемов по мобильной сети крайне нестабильна. Перед отправкой рекомендуем сжимать изображения средства платформы:
    
    КартинкаОригинал = Новый Картинка(ПутьКФайлу);
    // Сжимаем изображение до приемлемого качества (например, 70%)
    СжатыеДанные = КартинкаОригинал.ПолучитьДвоичныеДанныеСжатия(70);
    
  2. Разделение передачи шапки и тяжелых файлов: При передаче больших пакетов данных выгоднее сначала передавать текстовую часть документа (шапку и табличные части), а затем фоновым процессом отправлять фотографии по одной. Это предотвратит повторную отправку всего документа при обрыве связи.
  3. Переход на HTTP-сервисы (REST API): Для современных мобильных приложений рекомендуется использовать HTTP-сервисы вместо SOAP/WS. Они работают быстрее за счет отсутствия избыточных XML-оболочек SOAP Envelope и позволяют передавать файлы прямо в теле HTTP-запроса.
← На главную