При интеграции 1С с внешними веб-сервисами часто возникает необходимость отправки данных в формате JSON. Распространенной ошибкой или избыточным действием является сохранение сформированного JSON-пакета во временный файл на диске перед его отправкой. Рассмотрим, как избежать лишних операций ввода-вывода и работать напрямую с оперативной памятью, используя возможности платформы 1С:Предприятие 8.3.
Наиболее правильным и универсальным способом является использование встроенного объекта ЗаписьJSON. Вместо того чтобы указывать путь к файлу в методе ОткрытьФайл, мы воспользуемся методом УстановитьСтроку. Это позволит системе подготовить буфер в памяти.
Проанализируем пример кода, в котором мы упаковываем структуру данных в JSON и помещаем её в тело HTTP-запроса:
// 1. Подготовим данные в виде структуры
СтруктураЗапроса = Новый Структура;
СтруктураЗапроса.Вставить("ItemName", "Товар №1");
СтруктураЗапроса.Вставить("Quantity", 10);
// 2. Настроим параметры записи JSON (экранирование, переносы и т.д.)
ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, " ", Истина, ЭкранированиеСимволовJSON.Нет);
// 3. Инициализируем объект записи
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
// 4. Сериализуем объект 1С в формат JSON
ЗаписатьJSON(ЗаписьJSON, СтруктураЗапроса);
// 5. Извлекаем готовую строку
СтрокаJSON = ЗаписьJSON.Закрыть();
// 6. Формируем HTTP-запрос
HTTPЗапрос = Новый HTTPЗапрос("/api/v1/data");
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
В данном примере мы исключили этап записи на жесткий диск. Метод ЗаписьJSON.Закрыть() возвращает сформированную строку, которую мы сразу передаем в HTTPЗапрос.УстановитьТелоИзСтроки. Обратите внимание на важность использования ИспользованиеByteOrderMark.НеИспользовать — многие веб-сервисы некорректно обрабатывают наличие BOM-символов в начале JSON-строки.
Если структура данных максимально проста и не содержит вложенных объектов или спецсимволов, требующих экранирования, можно использовать обычную конкатенацию строк. Разберем этот вариант, который часто применяется для быстрой отладки или простых запросов.
ТелоЗапроса = "{""login"": """ + Объект.Логин + """, ""password"": """ + Объект.Пароль + """}";
HTTPЗапрос = Новый HTTPЗапрос(Ресурс);
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса);
Важно понимать: этот метод крайне не рекомендуется для сложных данных. Вы рискуете получить невалидный JSON, если в значении Логин встретятся кавычки или обратные слэши. Используйте этот способ только в самых тривиальных случаях.
Для высоконагруженных систем или при передаче очень больших объемов данных формирование одной гигантской строки может привести к нехватке оперативной памяти. В этом случае эффективно использовать ПотокВПамяти. Рассмотрим, как это реализовать:
Поток = Новый ПотокВПамяти();
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьПоток(Поток);
// Записываем данные в поток
ЗаписатьJSON(ЗаписьJSON, МассивДанных);
ЗаписьJSON.Закрыть();
// Получаем двоичные данные из потока
ДвоичныеДанныеТела = Поток.ЗакрытьИПолучитьДвоичныеДанные();
// Передаем в запрос напрямую как двоичные данные
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТела);
Этот метод является наиболее производительным, так как исключает лишнее преобразование "Двоичные данные -> Строка -> Двоичные данные" при формировании тела HTTP-пакета.
Если вам нужно передать объект метаданных целиком (например, справочник или документ), удобно использовать СериализаторXDTO. Он автоматически преобразует типы 1С в типы JSON.
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
// Используем глобальный объект СериализаторXDTO
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, СсылкаНаОбъект, НазначениеТипаXML.Явное);
СтрокаJSON = ЗаписьJSON.Закрыть();
Выясним причину популярности этого метода: он избавляет программиста от ручного создания структур и копирования каждого реквизита. Платформа сама подготовит дерево данных на основе схемы XDTO.
При использовании ЗаписьJSON мы можем управлять тем, как именно данные будут выглядеть "на выходе". Проанализируем ключевые параметры объекта ПараметрыЗаписиJSON:
/. Если вы передаете URL внутри JSON, установите ЭкранированиеСимволовJSON.Нет, чтобы ссылки оставались читаемыми.ДвоичныеДанные (например, скан документа), 1С автоматически преобразует его в Base64 строку при сериализации."content-type"), используйте объект Соответствие, так как в Структуре имена свойств должны соответствовать правилам именования переменных 1С.Логично предположить, что ответ от сервера нам также не нужно сохранять на диск. Посмотрим на пример десериализации ответа "на лету":
HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
// Получаем текст ответа напрямую в память
ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТекстОтвета);
// Преобразуем JSON обратно в структуру/соответствие 1С
Результат = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Таким образом, мы построили полный цикл обмена данными (отправка и получение), который работает исключительно в оперативной памяти, что значительно повышает скорость работы и надежность решения.