Работа с внешними веб-сервисами и обмен данными в формате JSON — одна из самых частых задач современного разработчика 1С. Однако стандартные средства платформы иногда выдают ошибки, которые могут поставить в тупик: от «Недопустимого состояния потока» до проблем с именами полей. В этой статье мы подробно разберем, почему возникают эти ошибки, и научимся правильно настраивать парсинг даже самых «капризных» JSON-строк.
Разберем ситуацию, когда в JSON приходят ключи вида "tem-53" или ключи, начинающиеся с цифр. Если мы используем стандартный метод ПрочитатьJSON(ЧтениеJSON, Ложь), 1С пытается преобразовать JSON в объект Структура. В 1С свойства структуры должны соответствовать правилам именования переменных: они не могут содержать дефисы (минус), пробелы или начинаться с цифр.
Проанализируем пример кода, который приводит к ошибке:
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТелоJSON);
// Вторая переменная "Ложь" указывает на чтение в Структуру
ДанныеОтвета = ПрочитатьJSON(ЧтениеJSON, Ложь);
Решение: Для обхода этого ограничения необходимо использовать объект Соответствие (Map). В отличие от структуры, ключом соответствия может быть любая строка. Рассмотрим правильный вариант вызова функции:
// Указываем Истина во втором параметре для использования Соответствия
ДанныеОтвета = ПрочитатьJSON(ЧтениеJSON, Истина);
// Обращение к данным будет выглядеть так:
ЗначениеНужногоПоля = ДанныеОтвета["tem-53"];
Выясним причину, почему это лучше: использование Соответствия гарантирует, что никакие данные не будут потеряны или искажены из-за особенностей синтаксиса встроенного языка 1С.
Эта ошибка часто возникает в двух случаях: либо когда мы пытаемся прочитать данные из закрытого объекта ЧтениеJSON, либо когда сам объект был инициализирован некорректно. Рассмотрим подробнее последовательность действий.
Разберем по шагам правильный алгоритм инициализации:
ЧтениеJSON.УстановитьСтроку() или открываем файл через ОткрытьФайл().ПрочитатьJSON().Закрыть().Если вы повторно вызываете методы чтения после того, как поток достиг конца файла или был закрыт, 1С выдаст ошибку состояния потока. Посмотрите на пример правильной обработки:
ЧтениеJSON = Новый ЧтениеJSON;
Попытка
ЧтениеJSON.УстановитьСтроку(Тело);
Данные = ПрочитатьJSON(ЧтениеJSON, Истина);
Исключение
Сообщить("Ошибка при разборе JSON: " + ОписаниеОшибки());
КонецПопытки;
ЧтениеJSON.Закрыть();
Иногда в JSON-ответе одно из полей само является строкой, содержащей JSON. В тексте это выглядит как обилие обратных слешей: "additional_data":"{\"email\":\"test@mail.ru\"}". Попытка вручную удалять эти символы через СтрЗаменить() — грубая ошибка, которая ломает структуру данных.
Рассмотрим правильный подход:
Нам нужно выполнить «двойной парсинг». Сначала мы читаем основной объект, а затем отдельно парсим строку из конкретного поля. Проанализируем пример:
// 1. Читаем основной JSON
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Тело);
ОсновнойОбъект = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
// 2. Достаем строку с вложенным JSON
СтрокаВложенныйJSON = ОсновнойОбъект["additional_data"];
// 3. Читаем вложенные данные
ЧтениеВложенный = Новый ЧтениеJSON;
ЧтениеВложенный.УстановитьСтроку(СтрокаВложенныйJSON);
ВложенныеДанные = ПрочитатьJSON(ЧтениеВложенный, Истина);
ЧтениеВложенный.Закрыть();
1С поддерживает несколько стандартов записи дат в JSON (ISO, Microsoft, JavaScript). Если формат в JSON не совпадает с тем, который ожидает 1С по умолчанию, вы получите ошибку или пустую дату. Выясним, как управлять этим процессом.
Функция ПрочитатьJSON имеет параметры для настройки чтения дат. Посмотрим на наиболее универсальные варианты:
// Чтение с явным указанием формата ISO (самый распространенный)
ДанныеISO = ПрочитатьJSON(ЧтениеJSON, Ложь, , ФорматДатыJSON.ISO);
// Если дата приходит в формате Microsoft (/Date.../)
ДанныеMS = ПрочитатьJSON(ЧтениеJSON, Ложь, , ФорматДатыJSON.Microsoft);
Важный нюанс по часовым поясам: При чтении дат в формате ISO 8601 (с буквой Z на конце), 1С автоматически конвертирует их в местное время сервера или сеанса. Если сервер находится в Москве (UTC+3), к времени из JSON прибавится 3 часа. Если вам нужно сохранить «чистое» время, используйте функцию восстановления или читайте дату как обычную строку, обрабатывая её позже через Дата().
При работе через HTTPСоединение вы можете получить код ответа 303 (See Other). Это не ошибка парсинга, это указание сервера, что данные нужно забрать по другому адресу. Платформа 1С не всегда автоматически следует таким редиректам.
Проанализируем, что нужно сделать при получении кода 303:
КодСостояния объекта HTTPОтвет.Location.
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 303 Тогда
НовыйАдрес = Ответ.Заголовки.Получить("Location");
// Здесь логика повторного запроса по НовомуАдресу
КонецЕсли;
Для того чтобы ваш код был устойчив к изменениям на стороне веб-сервиса, придерживайтесь следующих правил:
Истина), если вы не уверены на 100%, что ключи JSON всегда будут валидными именами переменных 1С.Попытка...Исключение вокруг методов УстановитьСтроку и ПрочитатьJSON.Помните, что корректная работа с JSON в 1С — это прежде всего правильная настройка объектов ЧтениеJSON и понимание того, в какой тип данных (Структура или Соответствие) вы преобразуете результат. Соблюдение этих инструкций позволит вам избежать большинства типовых ошибок и сделать интеграцию стабильной.