Работа с форматом JSON стала стандартом де-факто для обмена данными между 1С и внешними веб-сервисами. Несмотря на наличие встроенных инструментов, начинающие разработчики часто сталкиваются с трудностями при извлечении данных из вложенных структур или массивов. В этой статье мы подробно разберем, как правильно десериализовать строку JSON, как избежать типичных ошибок и обеспечим надежность вашего кода.
Для начала проанализируем базовый механизм чтения. Платформа 1С:Предприятие 8.3 предоставляет объект ЧтениеJSON и глобальную функцию ПрочитатьJSON(). Процесс всегда состоит из трех этапов: инициализация объекта чтения, установка источника данных (строка или файл) и само преобразование в объекты 1С (Структура, Соответствие или Массив).
Рассмотрим пример кода для обработки JSON из вашего вопроса:
// 1. Создаем объект чтения
ЧтениеJson = Новый ЧтениеJSON;
// 2. Загружаем строку в объект (СтрокаJSON - это ваша переменная с текстом)
ЧтениеJson.УстановитьСтроку(СтрокаJSON);
// 3. Читаем данные. По умолчанию функция создает Структуру
Данные = ПрочитатьJSON(ЧтениеJson);
// 4. Обязательно закрываем чтение
ЧтениеJson.Закрыть();
После выполнения этого кода в переменной Данные окажется объект типа Структура. Теперь мы можем обращаться к свойствам этой структуры напрямую через точку, если имена ключей в JSON соответствуют правилам именования переменных в 1С.
В вашем примере свойство phoneNumbers является массивом (на это указывают квадратные скобки [] в тексте JSON). Это означает, что после десериализации 1С создаст объект типа Массив. Распространенная ошибка — пытаться перебирать в цикле сам корневой объект Данные, надеясь найти в нем свойства. На самом деле, нужно обращаться конкретно к массиву.
Разберем по шагам, как правильно вывести все номера телефонов:
// Прямое обращение к массиву внутри структуры
МассивТелефонов = Данные.phoneNumbers;
// Обход массива в цикле
Для каждого Номер Из МассивТелефонов Цикл
Сообщить("Найден телефон: " + Номер);
КонецЦикла;
Выясним причину, почему в сообщении 3 возникла ошибка «Поле объекта не обнаружено». Это происходит по двум основным причинам:
Структуры в 1С обычно нечувствительны к регистру, при чтении JSON платформа строго следует стандарту. Если в JSON написано "phoneNumbers", а вы обратитесь к Данные.Phonenumbers, система может выдать ошибку в зависимости от настроек чтения.{"response": {"phoneNumbers": [...]}}, то обращение Данные.phoneNumbers вызовет ошибку, так как нужно обращаться Данные.response.phoneNumbers.Чтобы ваша программа не завершалась аварийно при отсутствии какого-либо ключа в ответе сервера (например, если у клиента нет телефонов и поле phoneNumbers просто отсутствует в JSON), мы рекомендуем использовать метод Свойство(). Это признак хорошего тона в разработке на 1С.
Проанализируем защищенный вариант кода:
Если Данные.Свойство("phoneNumbers") Тогда
// Мы уверены, что ключ существует
Телефоны = Данные.phoneNumbers;
// Дополнительная проверка: является ли это массивом
Если ТипЗнч(Телефоны) = Тип("Массив") Тогда
Для каждого ТекущийНомер Из Телефоны Цикл
Сообщить(ТекущийНомер);
КонецЦикла;
КонецЕсли;
Иначе
Сообщить("Свойство phoneNumbers не найдено в полученных данных.");
КонецЕсли;
Иногда ключи в JSON содержат символы, которые недопустимы для ключей Структуры (например, дефисы "phone-number" или если имя начинается с цифры). В этом случае функция ПрочитатьJSON по умолчанию может сработать некорректно или вы не сможете обратиться к полю через точку.
Посмотрим, как решить эту проблему, указав тип возвращаемого значения во втором параметре функции:
// Указываем, что хотим получить Соответствие, а не Структуру
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь); // Ложь во втором параметре (ИспользоватьСтруктуру)
// Теперь обращение идет через квадратные скобки, что позволяет использовать любые имена ключей
Если Данные.Получить("phone-number") <> Неопределено Тогда
Телефоны = Данные["phone-number"];
КонецЕсли;
Важно помнить, что в стандарте JSON нет типа данных «Дата». Обычно даты передаются как строки. Платформа 1С позволяет автоматизировать их преобразование. Для этого в функции ПрочитатьJSON используются параметры настройки, где можно указать формат даты (например, ISO) или даже передать собственную функцию-обработчик (функцию восстановления), которая будет вызываться для каждого элемента при чтении.
Если вы работаете с очень большими файлами JSON (сотни мегабайт), метод ПрочитатьJSON() может вызвать переполнение оперативной памяти, так как он загружает всё дерево объектов целиком. В таких ситуациях мы рекомендуем использовать потоковое чтение.
Вместо одной функции ПрочитатьJSON(), мы используем цикл по объекту ЧтениеJSON:
Пока ЧтениеJson.Прочитать() Цикл
ТипУзла = ЧтениеJson.ТипУзла;
Если ТипУзла = ТипУзлаЧтенияJSON.ИмяСвойства И ЧтениеJson.ТекущееЗначение = "phoneNumbers" Тогда
// Нашли нужное свойство, читаем следующее значение (начало массива)
ЧтениеJson.Прочитать();
// Здесь можно реализовать логику ручного разбора элементов массива
КонецЕсли;
КонецЦикла;
Подводя итог, можно сказать, что для решения вашей задачи достаточно правильно инициализировать ЧтениеJSON и помнить, что результат десериализации — это коллекция. Всегда проверяйте в отладчике тип переменной Данные: если это Структура, обращайтесь по имени свойства; если это Массив (в случае, если JSON начинается с [), используйте цикл Для каждого сразу по объекту Данные.