В «1С:Предприятие.Элементе Скрипте» представлены широкие возможности по работе с форматом JSON. Во встроенном языке используются специальные типы для работы с данным форматом, основными из которых являются СериализацияJson
, ЧтениеJson
и ЗаписьJson
. Вы можете автоматически преобразовать в/из JSON большинство типов встроенного языка.
Эти и другие встроенные средства позволяют осуществлять потоковую, объектную или смешанную формы работы с форматом JSON:
- При потоковой работе документ JSON не загружается в память целиком, а считывается по частям. Программа при этом осуществляет навигацию по структуре документа в соответствии с настройками, указанными пользователем. Такой способ удобен при работе с файлами большого размера и/или сложной структурой вложенности объектов.
- При объектной работе документ JSON загружается в память целиком и считывается в объект, например, соответствие или структуру данных. Такой способ удобен, когда требуется передавать данные как простой и относительно небольшой объект, поэтому объекты JSON используются в основном в API.
- При смешанной работе программа осуществляет навигацию по структуре документа потоковым способом, но, когда доходит до требуемого объекта, загружает его объектным способом.
Для тех, кто использует JSON версии JSON5 и выше (в которых поддерживаются однострочные комментарии)
Комментарий начинается с символов //
и заканчивается с концом строки. Содержимое комментария при чтении JSON игнорируется, то есть результат чтения JSON не включает содержимого комментариев и не содержит какой-либо информации о наличии комментариев.
Потоковый режим работы с JSON
Во встроенном языке для потокового ввода и вывода данных используются соответственно типы ЧтениеJson
и ЗаписьJson
.
В типе ЧтениеJson
существует метод для чтения значения JSON в указанный тип:
Кроме того, существуют методы для чтения значения JSON в один из конкретных типов:
ПрочитатьСодержимоеКакБайты()
,
ПрочитатьСодержимоеКакБулево()
,
ПрочитатьСодержимоеКакВремя()
,
ПрочитатьСодержимоеКакДата()
,
ПрочитатьСодержимоеКакДатаВремя()
,
ПрочитатьСодержимоеКакДлительность()
,
ПрочитатьСодержимоеКакМассив()
,
ПрочитатьСодержимоеКакМомент()
,
ПрочитатьСодержимоеКакСоответствие()
,
ПрочитатьСодержимоеКакСтроку()
,
ПрочитатьСодержимоеКакУуид()
,
ПрочитатьСодержимоеКакЧисло()
.
Объектный режим работы с JSON
Во встроенном языке для объектной работы с данными используются механизмы сериализации и десериализации. Сериализация используется для перевода структуры данных в формат, позволяющий передавать или хранить эти данные, например, в файле. Десериализация — обратная процедура. В «1С:Предприятие.Элементе Скрипте» для этого используется тип СериализацияJson
. Методы этого типа позволяют выполнить сериализацию (метод ЗаписатьОбъект()
и др.) в поток или строку или десериализацию (метод ПрочитатьОбъект()
и др.).
При сериализации порядок разбора значений следующий:
При десериализации порядок разбора значений следующий:
-
Нетипизированное чтение:
Сначала предпринимается попытка разобрать значения 4-х простых базовых типов:
И 2-х сложных:
Если разобрать значение не удалось, то будет выброшено исключение чтения JSON.
-
Типизированное чтение:
Сначала предпринимается попытка разобрать значения 4-х простых базовых типов, если указаны они или их базовые типы:
Если разобрать значение не удалось, то будет осуществляться обход всех доступных типов значения. Если в результате обхода значение разобрать удалось, но сразу несколькими типами, то будет выброшено исключение о неявном чтении.
Смешанный режим работы с JSON
При смешанной работе с JSON могут использоваться как типы ЧтениеJson
и ЗаписьJson
, так и тип СериализацияJson
. Например:
структура ФизическоеЛицо
пер Фамилия: Строка
пер Имя: Строка
пер Отчество: Строка
;
@НаСервере @ДоступноСКлиента
метод ПрочитатьФизическихЛиц()
пер ФизическиеЛицаJson =
"[
{
\"Фамилия\": \"Иванов\",
\"Имя\": \"Иван\",
\"Отчество\": \"Иванович\"
},
{
\"Фамилия\": \"Петров\",
\"Имя\": \"Петр\",
\"Отчество\": \"Петрович\"
}
]"
пер Чтение = новый ЧтениеJson(ФизическиеЛицаJson)
если не Чтение.Следующий()
возврат
;
если не Чтение.Следующий()
возврат
;
пока Чтение.ВидУзла != ВидУзлаJson.КонецМассива
пер ФизЛицо = Чтение.ПрочитатьСодержимое<ФизическоеЛицо>()
;
;
Или другой пример:
@НаСервере @ДоступноСКлиента
метод ПрочитатьОбращенияПользователей()
пер ОбращенияJson =
"[
{\"Пользователь\":
{
\"Фамилия\": \"Иванов\",
\"Имя\": \"Иван\",
\"Логин\": \"Иванов\"
},
\"Обращения\": [
{\"Категория\": \"Жалоба\", \"Текст\": \"текст1\"},
{\"Категория\": \"Вопрос\", \"Текст\": \"текст2\"}
]
},
{\"Пользователь\":
{
\"Фамилия\": \"Петров\",
\"Имя\": \"Петр\",
\"Логин\": \"Петров\"
},
\"Обращения\": [
{\"Категория\": \"Благодарность\", \"Текст\": \"текст3\"}
]
}
]"
пер Чтение = новый ЧтениеJson(ОбращенияJson)
если не Чтение.Следующий()
возврат
;
если не Чтение.Следующий()
возврат
;
пока Чтение.ВидУзла != ВидУзлаJson.КонецМассива
Чтение.Следующий()
Чтение.Следующий()
пер ДанныеПользователя = Чтение.ПрочитатьСодержимоеКакСоответствие()
Чтение.Следующий()
пер Обращения = Чтение.ПрочитатьСодержимоеКакМассив()
Чтение.Следующий()
;
;
При смешанной работе с JSON в качестве параметров методов ПрочитатьОбъект()
и ЗаписатьОбъект()
типа СериализацияJson
можно использовать экземпляры типов ЧтениеJson
и ЗаписьJson
. В таком случае при чтении и записи этих объектов будут использоваться те же потоки, что и при их создании.
перечисление ТипОплаты
Наличные,
@JsonЭлементПеречисления("КредитнаяКарта")
Карта умолчание
;
структура ИнформацияЗаказа
пер НомерЗаказа: Строка
пер ТипОплаты: ТипОплаты
пер Плательщик: Строка
;
метод СоздатьСписокЗаказов(): Массив<ИнформацияЗаказа>
пер Результат = новый Массив<ИнформацияЗаказа>()
Результат.Добавить(новый ИнформацияЗаказа("abc-322", ТипОплаты.Карта, "Иванов"))
Результат.Добавить(новый ИнформацияЗаказа("abc-323", ТипОплаты.Наличные, "Петров"))
Результат.Добавить(новый ИнформацияЗаказа("abc-324", ТипОплаты.Карта, "Сидоров"))
возврат Результат
;
@НаСервере @ДоступноСКлиента
метод ЗаписатьСписокЗаказовВJson()
пер Поток = новый СтроковыйПотокЗаписи()
знч Настройки = новый НастройкиЗаписиОбъектовJson()
пер Писатель = новый ЗаписьJson(Поток, Настройки)
Писатель.ЗаписатьНачалоОбъекта()
Писатель.Записать("Описание", "Список заказов")
Писатель.Записать("МеткаВремени", DateTime{2014-10-06T12:57:35})
Писатель.ЗаписатьИмяСвойства("Заказы")
Сериализация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 \н\н"
;
структура СтруктураАбоненты
пер Абоненты: Множество<СтруктураАбонент>
;
структура СтруктураАбонент
пер Наименование: Строка
пер Код: Строка
;
@НаСервере @ДоступноСКлиента
метод СериализоватьСтруктуру(): Строка
знч АбонентыОбъект = новый СтруктураАбоненты(новый Множество<СтруктураАбонент>())
АбонентыОбъект.Абоненты.Добавить(новый Структу раАбонент("Тестовый абонент", "123456"))
знч НастройкиЗаписи = новый НастройкиЗаписиОбъектовJson()
НастройкиЗаписи.ИспользуемыеИменаСвойств.Вставить(Тип<ТестЗаписиВJson>, {"ТипЗначения":"тип"})
знч Объект = новый ТестЗаписиВJson(Строка = "ТестоваяСтрока",
Число = 123,
Дата = Дата.Сейчас(),
Время = Время.Сейчас(),
ДатаВремя = ДатаВремя.Сейчас(),
Массив = ["Тестовый", "Массив", "Строка"],
Множество = {9,8,7,6},
Структура = АбонентыОбъект,
Байты = {0112AAEE FFB2 0011FFAA},
ТипЗначения = "ОписаниеТипаЗначения")
пер ТекстJSON = СериализацияJson.ЗаписатьОбъект(Объект, НастройкиЗаписи)
возврат ТекстJSON
;
@НаСервере @ДоступноСКлиента
метод ДесериализоватьСтруктуру(СтрокаJSON: Строка): Строка
знч НастройкиЧтения = новый НастройкиЧтенияОбъектовJson()
НастройкиЧтения.ПсевдонимыСвойств = {
Тип<ТестЗаписиВJson>: {
"ТипЗначения": {"тип"}
}
}
знч ПрочитанныйОбъект = СериализацияJson.ПрочитатьОбъект<ТестЗаписиВJson>(СтрокаJSON, Тип<ТестЗаписиВJson>, НастройкиЧтения)
знч ТипОбъекта = ПрочитанныйОбъект.ПолучитьТип().ВСтроку()
знч ПредставлениеОбъекта = ПрочитанныйОбъект.ВСтроку()
возврат "Прочитан объект типа: %ТипОбъекта\н\нСодержимое объекта: \н\н%ПредставлениеОбъекта"
;
Пример c использованием аннотации свойства структуры
@Локально
структура ТестЗаписиВJson
пер Строка: Строка
пер Число: Число
пер Дата: Дата
пер Время: Время
пер ДатаВремя: ДатаВремя
пер Массив: Массив<Строка>
пер Множество: Множество<Число>
пер Структура: СтруктураАбоненты
пер Байты: Байты
@JsonСвойство(Имя="тип", Псевдонимы={"тип_значения"})
пер ТипЗначения: Строка
;
метод ТестСериализацииJSON(): Строка
пер СтрокаJSON = СериализоватьСтруктуру()
пер СтрокаИзJSON = ДесериализоватьСтруктуру(СтрокаJSON)
возврат
"Результат сериализации: \н\н
%СтрокаJSON \н\н
Результат ДЕсериализации: \н\н
%СтрокаИзJSON \н\н"
;
структура СтруктураАбоненты
пер Абоненты: Множество<СтруктураАбонент>
;
структура СтруктураАбонент
пер Наименование: Строка
пер Код: Строка
;
@НаСервере @ДоступноСКлиента
метод СериализоватьСтруктуру(): Строка
знч АбонентыОбъект = новый СтруктураАбоненты(новый Множество<СтруктураАбонент>())
АбонентыОбъект.Абоненты.Добавить(новый СтруктураА бонент("Тестовый абонент", "123456"))
знч Объект = новый ТестЗаписиВJson(Строка = "ТестоваяСтрока",
Число = 123,
Дата = Дата.Сейчас(),
Время = Время.Сейчас(),
ДатаВремя = ДатаВремя.Сейчас(),
Массив = ["Тестовый", "Массив", "Строка"],
Множество = {9,8,7,6},
Структура = АбонентыОбъект,
Байты = {0112AAEE FFB2 0011FFAA},
ТипЗначения = "ОписаниеТипаЗначения")
пер ТекстJSON = СериализацияJson.ЗаписатьОбъект(Объект)
возврат ТекстJSON
;
@НаСервере @ДоступноСКлиента
метод ДесериализоватьСтруктуру(СтрокаJSON: Строка): Строка
знч ПрочитанныйОбъект = СериализацияJson.ПрочитатьОбъект<ТестЗаписиВJson>(СтрокаJSON, Тип<ТестЗаписиВJson>)
знч ТипОбъекта = ПрочитанныйОбъект.ПолучитьТип().ВСтроку()
знч ПредставлениеОбъекта = ПрочитанныйОбъект.ВСтроку()
возврат "Прочитан объект типа: %ТипОбъекта\н\нСодержимое объекта: \н\н%ПредставлениеОбъекта"
;
Теперь в полученном объекте JSON соответствующее поле будет называться тип
:
{
"Дата" : "2024-01-10",
"Время" : "19:27:03.857",
"Массив" : [
"Тестовый",
"Массив",
"Строка"
],
"тип" : "ОписаниеТипаЗначения",
"Строка" : "ТестоваяСтрока",
"Структура" : {
"Абоненты" : [
{
"Наименование" : "Тестовый абонент",
"Код" : "123456"
}
]
},
"Байты" : "ARKq7v-yABH_qg==",
"Множество" : [
9,
8,
7,
6
],
"Число" : 123,
"ДатаВремя" : "2024-01-10T19:27:03.857"
}
Передача объекта JSON с псевдонимом тип_значения
:
{
"Дата" : "2024-01-10",
"Время" : "19:27:03.857",
"Массив" : [
"Тестовый",
"Массив",
"Строка"
],
"тип_значения" : "ОписаниеТипаЗначения",
"Строка" : "ТестоваяСтрока",
"Структура" : {
"Абоненты" : [
{
"Наименование" : "Тестовый абонент",
"Код" : "123456"
}
]
},
"Байты" : "ARKq7v-yABH_qg==",
"Множество" : [
9,
8,
7,
6
],
"Число" : 123,
"ДатаВремя" : "2024-01-10T19:27:03.857"
}
Получение объекта с соответствующим псевдониму названием поля:
{Строка=ТестоваяСтрока, Число=123, Дата=2024-01-10, Время=19:27:03.857, ДатаВремя=2024-01-10T19:27:03.857, Массив=[Тестовый, Массив, Строка], Множество={9, 8, 7, 6}, Структура={Абоненты={{Наименование=Тестовый абонент, Код=123456}}}, Байты=0112aaeeffb20011ffaa, ТипЗначения=ОписаниеТипаЗначения}
Пример инициализации отсутствующих полей
структура Структура
пер Поле: Строка
пер Поле2: Строка = ""
пер Поле3: Строка?
пер Поле4: Строка? = ""
пер Поле5: Строка|Число?
;
@НаСервере @ДоступноСКлиента
метод ЧтениеИзJson()
знч JSON = "{}"
знч Настройки = новый НастройкиЧтенияОбъектовJson()
Настройки.ИнициализироватьОтсутствующиеПоля = Истина
знч Результат = СериализацияJson.ПрочитатьОбъект<Структура>(JSON, Тип<Структура>, Настройки)
;
структура СтруктураСКоллекциями
пер Поле: Массив<Строка>?
пер Поле2: Массив<Строка>
;
@НаСервере @ДоступноСКлиента
метод ЧтениеСтруктурыСКоллекциями()
знч JSON = "{}"
знч Настройки = новый НастройкиЧтенияОбъектовJson()
Настройки.ИнициализироватьПустыеКоллекции = Истина
пер Результат = СериализацияJson.ПрочитатьОбъект<СтруктураСКоллекциями>(JSON, Тип<СтруктураСКоллекциями>, Настройки)
;