Как распарсить JSON-ответ от WinHttp в структуру 1С

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

При интеграции 1С со сторонними веб-сервисами и API часто возникает задача отправки HTTP-запроса и последующей обработки полученного ответа. Веб-серверы обычно возвращают данные в формате JSON. Разберем по шагам, как правильно преобразовать строку JSON в структуру или соответствие средствами платформы 1С, а также рассмотрим особенности работы с COM-объектом WinHttp.WinHttpRequest.5.1 и современные штатные альтернативы.

Штатный разбор JSON в платформе 1С

Начиная с версии платформы 8.3.6, в 1С реализована встроенная поддержка работы с форматом JSON. Для десериализации (преобразования строки JSON в объекты 1С) используется объект ЧтениеJSON и системная функция ПрочитатьJSON().

Рассмотрим подробнее стандартный алгоритм обработки ответа:

  1. Инициализируем объект ЧтениеJSON.
  2. Загружаем полученную строку с помощью метода УстановитьСтроку().
  3. Вызываем функцию ПрочитатьJSON(), передавая ей объект чтения.
  4. Закрываем поток чтения методом Закрыть().

Посмотрим на практический пример функции, которая принимает JSON-строку и возвращает структуру 1С:


Функция ПреобразоватьJSONВСтруктуру(Знач СтрокаJSON) Экспорт
    
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(СтрокаJSON);
    
    Результат = ПрочитатьJSON(Чтение);
    
    Чтение.Закрыть();
    
    Возврат Результат;
    
КонецФункции

Если передать в эту функцию строку {"status":"ok","ballance":"50.00","user_id":1584}, на выходе мы получим объект Структура с соответствующими ключами и значениями, к которым можно обращаться стандартным способом: Результат.status, Результат.ballance и Результат.user_id.

Важная особенность: чтение в Соответствие вместо Структуры

Проанализируем ситуацию, когда имена свойств в JSON содержат спецсимволы, дефисы, пробелы или начинаются с цифры (например, {"user-id": 1584, "1st_field": "test"}). Имена ключей в Структуре 1С подчиняются правилам формирования идентификаторов встроенного языка, поэтому при попытке разобрать такой JSON в структуру платформа вызовет исключение.

Чтобы избежать ошибки, во второй параметр функции ПрочитатьJSON() передается флаг Истина (чтение объектов JSON в Соответствие):


Функция ПреобразоватьJSONВСоответствие(Знач СтрокаJSON) Экспорт
    
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(СтрокаJSON);
    
    // Второй параметр Истина указывает читать JSON-объекты как Соответствие
    Результат = ПрочитатьJSON(Чтение, Истина);
    
    Чтение.Закрыть();
    
    Возврат Результат;
    
КонецФункции

В данном случае обращение к элементам будет происходить через получение значения по ключу: Результат["user-id"].

Нюансы работы с COM-объектом WinHttp.WinHttpRequest.5.1

При использовании COM-объекта WinHttp.WinHttpRequest.5.1 разработчики часто сталкиваются с двумя критическими проблемами:

  1. Проблема кодировки символов (UTF-8): Свойство ResponseText может вернуть искаженные кириллические символы («кракозябры»), если сервер не вернул явный заголовок с указанием кодировки. В таком случае надежнее получать бинарные данные через ResponseBody и декодировать их в строку 1С через ДвоичныеДанные или объект ADODB.Stream.
  2. Кроссплатформенность: COM-технология работает исключительно в операционной системе Windows. Если сервер 1С работает под управлением Linux, вызов Новый COMОбъект("WinHttp.WinHttpRequest.5.1") приведет к аварийному завершению с ошибкой.

Рекомендуемая альтернатива: штатные объекты HTTP-клиента

В современной разработке рекомендуется полностью отказаться от COM-объекта WinHttp в пользу штатных объектов платформы: HTTPСоединение, HTTPЗапрос и HTTPОтвет.

Посмотрим на пример отправки запроса и разбора ответа штатными средствами платформы:


Функция ВыполнитьЗапросКСерверу(Знач Сервер, Знач Ресурс) Экспорт
    
    Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL());
    Запрос = Новый HTTPЗапрос(Ресурс);
    Запрос.Заголовки.Вставить("Accept", "application/json");
    
    Ответ = Соединение.Получить(Запрос);
    
    Если Ответ.КодСостояния = 200 Тогда
        СтрокаJSON = Ответ.ПолучитьТелоКакСтроку("UTF-8");
        
        Чтение = Новый ЧтениеJSON;
        Чтение.УстановитьСтроку(СтрокаJSON);
        Данные = ПрочитатьJSON(Чтение);
        Чтение.Закрыть();
        
        Возврат Данные;
    Иначе
        ВызватьИсключение "Ошибка HTTP-запроса: " + Ответ.КодСостояния;
    КонецЕсли;
    
КонецФункции

Преимущества штатного подхода: метод ПолучитьТелоКакСтроку() гарантирует корректную работу с кодировкой UTF-8, код полностью кроссплатформенен и работает как на клиенте, так и на сервере под любой операционной системой.

← На главную