Работа с JSON
В «1С:Шине» представлены широкие возможности по работе с форматом JSON. Во встроенном языке используются специальные типы для работы с данным форматом, основными из которых являются СериализацияJson, ЧтениеJson и ЗаписьJson. Вы можете автоматически преобразовать в/из JSON большинство типов встроенного языка.
Эти и другие встроенные средства позволяют осуществлять потоковую, объектную или смешанную формы работы с форматом JSON:
- При потоковой работе документ JSON не загружается в память целиком, а считывается по частям. Программа при этом осуществляет навигацию по структуре документа в соответствии с настройками, указанными пользователем. Такой способ удобен при работе с файлами большого размера и/или сложной структурой вложенности объектов.
- При объектной работе документ JSON загружается в память целиком и считывается в объект, например, соответствие или структура данных. Такой способ удобен, когда требуется передавать данные как простой и относительно небольшой объект, поэтому объекты JSON используются в основном в API.
- При смешанной работе программа осуществляет навигацию по структуре документа потоковым способом, но когда доходит до требуемого объекта, загружает его объектным способом.
Для тех, кто использует JSON версии JSON5 и выше (в которых поддерживаются однострочные комментарии)
Комментарий начинается с символов //
и заканчивается с концом строки.
Содержимое комментария при чтении JSON игнорируется, то есть результат чтения JSON не
включает содержимого комментариев и не содержит какой-либо информации о наличии
комментариев.
Потоковый режим работы с JSON
Во встроенном языке для потокового ввода и вывода данных используются соответственно типы ЧтениеJson и ЗаписьJson.
В типе ЧтениеJson существует метод для чтения значения JSON в указанный тип:
- ПрочитатьСодержимое, который использует обобщённый тип данных и принимает как аргумент объект типа НастройкиЧтенияОбъектовJson, как и в примере выше для СериализацияJson.
Кроме того, существуют методы для чтения значения JSON в один из конкретных типов:
- ПрочитатьСодержимоеКакБайты,
- ПрочитатьСодержимоеКакБулево,
- ПрочитатьСодержимоеКакВремя,
- ПрочитатьСодержимоеКакДата,
- ПрочитатьСодержимоеКакДатаВремя,
- ПрочитатьСодержимоеКакДлительность,
- ПрочитатьСодержимоеКакМассив,
- ПрочитатьСодержимоеКакМомент,
- ПрочитатьСодержимоеКакСоответствие,
- ПрочитатьСодержимоеКакСтроку,
- ПрочитатьСодержимоеКакУуид,
- ПрочитатьСодержимоеКакЧисло.
Объектный режим работы с JSON
Во встроенном языке для объектной работы с данным используются механизмы сериализации и десериализации. Сериализация используется для перевода структуры данных в формат, позволяющий передавать или хранить эти данные, например, в файле. Десериализация — обратная процедура. В «1С:Шине» для этого используется тип СериализацияJson. Методы этого типа позволяют выполнить сериализацию (метод ЗаписатьОбъект и др.) в поток или строку или десериализацию (метод ПрочитатьОбъект и др.).
Смешанный режим работы с JSON
// Создаём структуру для чтения данных из JSON
структура ФизическоеЛицо
пер Фамилия: Строка
пер Имя: Строка
пер Отчество: Строка
;
// Используем потоковое чтение с помощью типа ЧтениеJson
метод ПрочитатьФизическихЛиц()
пер ФизическиеЛицаJson =
"[
{
\"Фамилия\": \"Иванов\",
\"Имя\": \"Иван\",
\"Отчество\": \"Иванович\"
},
{
\"Фамилия\": \"Петров\",
\"Имя\": \"Петр\",
\"Отчество\": \"Петрович\"
}
]"
пер ЧтениеМассива = новый ЧтениеJson(ФизическиеЛицаJson)
// позиционируемся на начало массива
если не Чтение.Следующий()
возврат
;
// позиционируемся на первый элемент массива
если не Чтение.Следующий()
возврат
;
// Считываем данные из JSON в структуру для дальнейшего использования как объекта
пока ЧтениеМассива.ВидУзла != ВидУзлаJson.КонецМассива
пер ФизЛицо = ЧтениеМассива.ПрочитатьСодержимое<ФизическоеЛицо>()
// Записываем полученные данные в базу
;
;
или// Используем потоковое чтение с помощью типа ЧтениеJson
метод ПрочитатьОбращенияПользователей()
пер ОбращенияJson =
"[
{\"Пользователь\":
{
\"Фамилия\": \"Иванов\",
\"Имя\": \"Иван\",
\"Логин\": \"Иванов\"
},
\"Обращения\": [
{\"Категория\": \"Жалоба\", \"Текст\": \"текст1\"},
{\"Категория\": \"Вопрос\", \"Текст\": \"текст2\"}
]
},
{\"Пользователь\":
{
\"Фамилия\": \"Петров\",
\"Имя\": \"Петр\",
\"Логин\": \"Петров\"
},
\"Обращения\": [
{\"Категория\": \"Благодарность\", \"Текст\": \"текст3\"}
]
}
]"
пер Чтение = новый ЧтениеJson(ОбращенияJson)
// позиционируемся на начало массива
если не Чтение.Следующий()
возврат
;
// позиционируемся на первый элемент массива
если не Чтение.Следующий()
возврат
;
пока Чтение.ВидУзла != ВидУзлаJson.КонецМассива
// позиционируемся на свойство Пользователь
Чтение.Следующий()
// позиционируемся на начало объекта Пользователь
Чтение.Следующий()
// Считываем данные из JSON в коллекции для дальнейшего использования как объектов
// читаем данные пользователя в соответствие
пер ДанныеПользователя = Чтение.ПрочитатьСодержимоеКакСоответствие()
// после этого вызова ЧтениеJson будет спозиционировано на свойство Обращения
// позиционируемся на начало массива
Чтение.Следующий()
// читаем массив обращений
пер Обращения = Чтение.ПрочитатьСодержимоеКакМассив()
// после этого вызова ЧтениеJson будет спозиционировано на токен КонецОбъекта
// Возвращаемся к потоковому чтению JSON
// переходим к следующему элементу массива
Чтение.Следующий()
;
;
Настройки чтения и записи объектов JSON
Для настройки чтения, записи и сериализации объектов JSON используются специальные типы, основными из которых являются НастройкиЧтенияОбъектовJson и НастройкиЗаписиОбъектовJson. Они позволяют указывать, как именно системе обрабатывать свойства объектов JSON, например, нужно ли игнорировать неизвестные поля, инициализировать пустые поля, использовать псевдонимы свойств при совпадении имен и так далее.
Допустим, файл JSON из внешнего источника может содержать свойства, имена которых
совпадают с используемыми во встроенном языке ключевыми
словами, литералами и т. д. Например,
нельзя использовать слово Тип
в имени переменной, так как уже
существует такой литерал (подробнее см. в Имена переменных). Тем не
менее, для обхода таких ограничений можно использовать настройки из списков выше:
ПсевдонимыСвойств
при чтении и
ИспользуемыеИменаСвойств
при записи.
- @JsonИгнорироватьСвойство
-
Данной аннотацией помечается поле структуры. При сериализации структуры в JSON-объект свойство, соответствующее полю, отмеченному данной аннотацией, не будет записано. При десериализации JSON-объекта такое поле будет заполнено значением по умолчанию, даже если в считываемых данных содержалось другое значение. При отсутствии значения по умолчанию для типа поля будет выброшено исключение.
Данная аннотация является аналогом следующей настройки:- НастройкиЗаписиОбъектовJson.ИгнорируемыеСвойства
- @JsonСвойство(Имя, БезОбработки, Псевдонимы)
- Данной аннотацией помечается поле структуры. Позволяет задать настройки
для свойства, аналогичные следующим настройкам:
- НастройкиЗаписиОбъектовJson.ИспользуемыеИменаСвойств
(параметр
Имя
) - НастройкиЗаписиОбъектовJson.ЗаписьСвойствБезОбработки
(параметр
БезОбработки
) - НастройкиЧтенияОбъектовJson.ПсевдонимыСвойств
(параметр
Псевдонимы
)
- НастройкиЗаписиОбъектовJson.ИспользуемыеИменаСвойств
(параметр
- @JsonОбъект(ПропускатьПустыеЗначения, РежимЗаписиТипа, ИгнорироватьНеизвестные)
- Данной аннотацией помечается структура. Позволяет задать настройки для
объекта, аналогичные следующим настройкам:
- НастройкиЗаписиОбъектовJson.ПропускатьНеопределено
и
НастройкиЗаписиОбъектовJson.ПропускатьПустыеКоллекции
(параметр
ПропускатьПустыеЗначения
) - НастройкиЧтенияОбъектовJson.ИнициализироватьОтсутствующиеПоляи
НастройкиЧтенияОбъектовJson.ИнициализироватьПустыеКоллекции
(параметр
ПропускатьПустыеЗначения
) - НастройкиЗаписиОбъектовJson.РежимЗаписиТипа
(параметр
РежимЗаписиТипа
) - НастройкиЧтенияОбъектовJson.ИгнорироватьНеизвестныеСвойства
(параметр
ИгнорироватьНеизвестные
)
- НастройкиЗаписиОбъектовJson.ПропускатьНеопределено
и
НастройкиЗаписиОбъектовJson.ПропускатьПустыеКоллекции
(параметр
Пример
@Локально
структура ТестЗаписиВJson
пер Строка: Строка
пер Число: Число
пер Дата: Дата
пер Время: Время
пер ДатаВремя: ДатаВремя
пер Массив: Массив<Строка>
пер Множество: Множество<Число>
пер Объект: Справочник1.Объект
пер Байты: Байты
пер ТипЗначения: Строка
;
метод ТестСериализацииJSON(Запрос: HttpСервисЗапрос)
пер Результат = ""
пер Ответ = Запрос.Ответ
пер СтрокаJSON = СериализоватьСтруктуру()
пер СтрокаИзJSON = ДесериализоватьСтруктуру(СтрокаJSON)
Результат =
"Результат сериализации: \н\н
%СтрокаJSON \н\н
Результат ДЕсериализации: \н\н
%СтрокаИзJSON \н\н"
Ответ.УстановитьТело(Результат)
;
// Использование псевдонимов свойств
метод СериализоватьСтруктуру(): Строка
знч НастройкиЗаписи = новый НастройкиЗаписиОбъектовJson()
НастройкиЗаписи.ИспользуемыеИменаСвойств.Вставить(Тип<ТестЗаписиВJson>, {"ТипЗначения":"type"})
знч ОбъектСправочника = новый Справочник1.Объект()
ОбъектСправочника.Наименование = "Тестовый абонент"
ОбъектСправочника.Код = "123456"
знч Объект = новый ТестЗаписиВJson(Строка = "ТестоваяСтрока",
Число = 123,
Дата = Дата.Сейчас(),
Время = Время.Сейчас(),
ДатаВремя = ДатаВремя.Сейчас(),
Массив = ["Тестовый", "Массив", "Строка"],
Множество = {9,8,7,6},
Объект = ОбъектСправочника,
Байты = ПолучитьДДФайла(),
ТипЗначения = "ОписаниеТипаЗначения")
пер ТекстJSON = СериализацияJson.ЗаписатьОбъект(Объект, НастройкиЗаписи)
возврат ТекстJSON
;
метод ДесериализоватьСтруктуру(СтрокаJSON: Строка): Строка
знч Псевдонимы = {
"ТипЗначения": {"value_type"}
}
знч НастройкиЧтения = новый НастройкиЧтенияОбъектовJson()
НастройкиЧтения.ПсевдонимыСвойств[Тип<ТестЗаписиВJson>] = Псевдонимы
знч ПрочитанныйОбъект = СериализацияJson.ПрочитатьОбъект(СтрокаJSON, Тип<ТестЗаписиВJson>, НастройкиЧтения)
знч ТипОбъекта = ПрочитанныйОбъект.ПолучитьТип().ВСтроку()
знч ПредставлениеОбъекта = ПрочитанныйОбъект.ВСтроку()
возврат "Прочитан объект типа: %ТипОбъекта\н\нСодержимое объекта: \н\н%ПредставлениеОбъекта"
;
Пример c использованием аннотации свойства структуры
@Локально
структура ТестЗаписиВJson
пер Строка: Строка
пер Число: Число
пер Дата: Дата
пер Время: Время
пер ДатаВремя: ДатаВремя
пер Массив: Массив<Строка>
пер Множество: Множество<Число>
пер Объект: Справочник1.Объект
пер Байты: Байты
@JsonСвойство(Имя="type", Псевдонимы={"value_type"})
пер ТипЗначения: Строка
;
метод ТестСериализацииJSON(Запрос: HttpСервисЗапрос)
пер Результат = ""
пер Ответ = Запрос.Ответ
пер СтрокаJSON = СериализоватьСтруктуру()
пер СтрокаИзJSON = ДесериализоватьСтруктуру(СтрокаJSON)
Результат =
"Результат сериализации: \н\н
%СтрокаJSON \н\н
Результат ДЕсериализации: \н\н
%СтрокаИзJSON \н\н"
Ответ.УстановитьТело(Результат)
;
// Использование псевдонимов свойств
метод СериализоватьСтруктуру(): Строка
знч ОбъектСправочника = новый Справочник1.Объект()
ОбъектСправочника.Наименование = "Тестовый абонент"
ОбъектСправочника.Код = "123456"
знч Объект = новый ТестЗаписиВJson(Строка = "ТестоваяСтрока",
Число = 123,
Дата = Дата.Сейчас(),
Время = Время.Сейчас(),
ДатаВремя = ДатаВремя.Сейчас(),
Массив = ["Тестовый", "Массив", "Строка"],
Множество = {9,8,7,6},
Объект = ОбъектСправочника,
Байты = ПолучитьДДФайла(),
ТипЗначения = "ОписаниеТипаЗначения")
пер ТекстJSON = СериализацияJson.ЗаписатьОбъект(Объект)
возврат ТекстJSON
;
метод ДесериализоватьСтруктуру(СтрокаJSON: Строка): Строка
знч ПрочитанныйОбъект = СериализацияJson.ПрочитатьОбъект(СтрокаJSON, Тип<ТестЗаписиВJson>)
знч ТипОбъекта = ПрочитанныйОбъект.ПолучитьТип().ВСтроку()
знч ПредставлениеОбъекта = ПрочитанныйОбъект.ВСтроку()
возврат "Прочитан объект типа: %ТипОбъекта\н\нСодержимое объекта: \н\н%ПредставлениеОбъекта"
;