Как правильно передать булево значение в формате JSON через HTTP-сервис 1С

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

При интеграции 1С с внешними системами через HTTP-сервисы разработчики часто сталкиваются с проблемой передачи логических значений (тип Булево). В формате JSON значения true и false являются литералами и не должны обрамляться кавычками. Однако некорректное использование встроенных функций 1С или ошибки при формировании тела ответа могут привести к тому, что принимающая сторона получит либо строку "true", либо непонятную последовательность символов («абракадабру»).

В этой статье мы подробно разберем, почему возникают такие ошибки, как работает механизм сериализации в 1С и как правильно сформировать HTTP-ответ, чтобы данные интерпретировались корректно.

Разбор типичных ошибок при передаче Булево

Рассмотрим ситуацию, с которой столкнулся автор темы. При попытке передать признак основного договора is_main, программист использовал несколько подходов, каждый из которых содержал свои нюансы.

Ошибка №1: Конкатенация со строкой

Часто разработчики пытаются принудительно сформировать текстовое представление значения следующим образом:


строкаДанныхДог.is_main = "" + ?(стрДоговор.is_main, "true", "false");

Проанализируем этот код. Здесь используется тернарный оператор, который возвращает строку "true" или "false". При дальнейшей обработке методом ЗаписатьJSON, система увидит, что в поле структуры записан тип Строка, и автоматически добавит кавычки. В итоге в JSON-пакете придет "is_main": "true". Если веб-сервис на стороне получателя ожидает строгий тип boolean, он выдаст ошибку или проигнорирует поле.

Ошибка №2: Использование функции XMLСтрока

В некоторых сообщениях предлагалось использовать функцию XMLСтрока(Значение). Давайте разберем, почему это не подходит для JSON, и как это можно было бы отладить с помощью аналога Postman на платформе 1С:


строкаДанныхДог.is_main = XMLСтрока(стрДоговор.is_main);

Функция XMLСтрока для булева значения действительно возвращает английские слова "true" или "false", но она возвращает их в виде строкового типа данных 1С. Сериализатор JSON воспринимает это как текст и снова упаковывает в кавычки. Результат будет таким же некорректным, как и в первом случае.

Правильный способ: Прямая передача типа Булево

Для того чтобы в итоговом JSON-файле значение отобразилось как литерал без кавычек, в структуру (или массив) необходимо передавать «чистое» значение типа Булево. Платформа 1С при записи JSON сама определит тип и преобразует его в соответствующий стандарт.

Рассмотрим правильный алгоритм формирования данных в цикле:


Для каждого стрДоговор Из ДоговораКонтрагента Цикл
    строкаДанныхДог = Новый Структура("id, name, is_main");
    строкаДанныхДог.id = Строка(стрДоговор.Ссылка.УникальныйИдентификатор());
    строкаДанныхДог.name = стрДоговор.Наименование;
    
    // Передаем значение как есть, без преобразований в строку
    // Если в стрДоговор.is_main уже Булево, просто присваиваем
    строкаДанныхДог.is_main = стрДоговор.is_main; 
    
    ДоговораДанные.Добавить(строкаДанныхДог);
КонецЦикла;

Выясним причину, почему иногда даже при таком подходе возникают проблемы. Если значение получается из запроса, например, через конструкцию ЕСТЬ НЕ NULL, важно убедиться, что поле действительно имеет тип Булево, а не является составным типом. Для надежности можно использовать явное приведение типов: Булево(стрДоговор.is_main).

Сериализация в JSON и формирование HTTP-ответа

После того как мы подготовили массив структур с правильными типами данных, нам нужно превратить его в строку JSON. Для этого используем объекты ЗаписьJSON и ПараметрыЗаписиJSON.

Посмотрим на пример кода, который гарантирует правильный результат:


ЗаписьJSON = Новый ЗаписьJSON;
// Устанавливаем настройки записи, если это необходимо
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, " ", Истина);

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

СтрокаРезультат = ЗаписьJSON.Закрыть();

Ответ = Новый HTTPСервисОтвет(200);
// Критически важный момент: указываем кодировку UTF-8
Ответ.УстановитьТелоИзСтроки(СтрокаРезультат, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

Разберем, почему важна настройка КодировкаТекста.UTF8 в методе УстановитьТелоИзСтроки. В обсуждении упоминалась «абракадабра» в ответе (символы вида РњР°Р). Это классический признак того, что данные, записанные в UTF-8, интерпретируются как Windows-1251. Если не указать кодировку явно, 1С может использовать системную кодировку сервера, что приведет к искажению данных на стороне веб-сайта, а в более сложных случаях может потребоваться обработка сжатого в Zip http-ответа.

Почему «магия» иногда срабатывает сама?

В сообщении №12 автор отметил, что проблема решилась «сама собой» после возврата к исходному коду. Проанализируем ситуацию: скорее всего, в процессе экспериментов были очищены временные данные или исправлена логика формирования структуры, где вместо "true" (строка) стало попадать Истина (булево).

Однако полагаться на магию не стоит. Для стабильной работы интеграции всегда следуйте трем правилам:

  1. Контроль типа: В структуру для JSON должны попадать только типы Булево, Число, Строка, Дата (которая требует настройки формата) или NULL.
  2. Отказ от ручного форматирования: Никогда не пишите "true" вручную, если хотите получить логический тип. Предоставьте это системному методу ЗаписатьJSON.
  3. Явное указание заголовков: Всегда устанавливайте Content-Type: application/json и кодировку utf-8 в объекте HTTPСервисОтвет.

Итоговый пример надежного кода

Соберем все рекомендации в один рабочий пример, который можно использовать в HTTP-сервисе для возврата списка договоров:


Функция ПолучитьКонтрагентов(Запрос)
    
    ДоговораДанные = Новый Массив;
    
    // Предположим, мы получили выборку из базы
    Выборка = Справочники.ДоговорыКонтрагентов.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        ДанныеДог = Новый Структура;
        ДанныеДог.Вставить("id", Строка(Выборка.Ссылка.УникальныйИдентификатор()));
        ДанныеДог.Вставить("name", Выборка.Наименование);
        // Гарантируем тип Булево
        ДанныеДог.Вставить("is_main", Булево(Выборка.ОсновнойДоговор)); 
        
        ДоговораДанные.Добавить(ДанныеДог);
    КонецЦикла;
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, ДоговораДанные);
    JSONСтрока = ЗаписьJSON.Закрыть();
    
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.УстановитьТелоИзСтроки(JSONСтрока, КодировкаТекста.UTF8);
    Ответ.Заголовки.Вставить("Content-Type", "application/json");
    
    Возврат Ответ;
    
КонецФункции

Использование этого подхода гарантирует, что ваше поле is_main придет на сайт в виде true или false без лишних кавычек, а кодировка текста будет соответствовать международным стандартам обмена данными, что позволит легко подключиться к нему через универсальный Python-коннектор к 1С.

← На главную