Заметки из Зазеркалья

26.01.2015

Сериализация прикладных типов 1С:Предприятия в JSON

Реализовано в версии 8.3.7.1759.

Некоторое время назад мы рассказывали о том, что в платформе реализованы средства работы с JSON. Потоковая запись/чтение и сериализация примитивных типов и коллекций.

Теперь мы рады рассказать вам о том, что мы полностью автоматизировали работу с JSON и реализовали в платформе третью группу средств. Они позволяют сериализовать в JSON прикладные типы 1С:Предприятия: ссылки, объекты, наборы записей и вообще любые типы, для которых поддерживается XDTO сериализация. Конечно же, мы обеспечили и обратную операцию - десериализацию.

Зачем это нужно

Прежде всего, и в основном, XDTO сериализацию в JSON мы рекомендуем использовать при обмене данными между двумя прикладными решениями 1С:Предприятия. По сравнению с XML формат JSON более компактный, сериализация/десериализация в/из JSON выполняется быстрее. Кроме этого мы предприняли дополнительные меры для того, чтобы сократить объём передаваемых данных.

Кроме обмена между приложениями 1С:Предприятия этот механизм можно использовать и для обмена с внешними системами, готовыми принимать типы данных 1С:Предприятия. Например, XDTO сериализацию в JSON можно использовать для организации собственного HTTP интерфейса прикладного решения. Сервис на платформе 1С:Предприятия будет формировать ответ в памяти в виде строки JSON. А затем передавать её при помощи объекта HTTPСервисОтвет. Реализованный нами механизм сериализации полностью соответствует стандарту JSON. Поэтому внешняя система не должна испытывать каких-либо трудностей с десериализацией.

Использование XDTO сериализации в JSON для других задач видится нам маловероятным. Потому что если внешняя система не готова работать с прикладными типами 1С:Предприятия, то зачем их ей передавать? А если предполагается обмениваться только примитивными типами и коллекциями, то для этой задачи хорошо подходят методы ПрочитатьJSON() и ЗаписатьJSON(), о которых мы рассказывали ранее.

Как это выглядит

Простейший код, выполняющий сериализацию элемента справочника, может выглядеть так:

В результате будет получен файл JSON следующего содержания:

{
	"#type": "jcfg:CatalogObject.Контрагенты",
	"#value": {
		"IsFolder": false,
		"Ref": "3d710076-8d04-11dc-8ca0-000d8843cd1b",
		"DeletionMark": false,
		"Parent": "9d5c422c-8c4c-11db-a9b0-00055d49b45e",
		"Code": "000000012",
		"Description": "Мосхлеб ОАО",
		"Регион": "9d5c422f-8c4c-11db-a9b0-00055d49b45e",
		"Индекс": "456789",
		"Страна": "Россия",
		"Город": "Москва",
		"Улица": "Петровка",
		"Дом": "12",
		"Телефон": "+7(999)234-78-64",
		"ЭлектроннаяПочта": "mh@hleb.ru",
		"Факс": "",
		"ВебСайт": "",
		"ВидЦен": "9d5c4225-8c4c-11db-a9b0-00055d49b45e",
		"ДополнительнаяИнформация": "Поставка хлеба",
		"КонтактноеЛицо": "Громышева П.Р.",
		"Широта": 55.762744,
		"Долгота": 37.618102
	}
}

Десериализацию такого файла можно выполнить следующим кодом:

В результате будет получен элемент справочника Контрагенты с наименованием Мосхлеб ОАО и кодом 000000012.

Особенности сериализации

Как вы уже могли заметить, сериализация/десериализация выполняется с помощью объекта СериализаторXDTO. Поэтому получаемая структура документа имеет «родовые черты» XML, JSON получается «похожим» на XML. Это оказывает отрицательное влияние и на «читаемость» и на компактность файла. Это своеобразная «плата» за удобства, получаемые от использования XDTO. Если же «чистота» получаемого JSON имеет для вас решающее значение, мы рекомендуем использовать инструменты, о которых мы рассказывали ранее.

Общие принципы сериализации в JSON идентичны XDTO сериализации в XML. В частности:

  • Структура данных соответствует структуре XML документа;
  • Имеются незначительные отличия, связанные с особенностями хранения типов и представлением массивов в JSON;
  • Порядок и состав свойств JSON соответствует структуре объекта конфигурации и не может изменяться.

Кроме этого есть одна важная особенность. В отличие от XML, для записи начала объекта JSON нет необходимости указывать его имя. По этой причине сериализация/десериализация JSON может выполняться одним из двух способов.

Либо при сериализации вы указываете явное назначение типа и потом десериализуете без указания типа считываемого значения:

Либо вы сериализуете в JSON без явного назначения типа. Но тогда тип нужно будет указать при десериализации:

Ещё одна особенность сериализации заключается в том, что мы стремились оптимизировать объём результирующего файла. Поэтому для встроенных типов платформы пространства имен не записываются полностью в отдельном свойстве JSON, а указываются в виде префикса перед типом:

В данном случае префикс jcfg обозначает пространство имён http://v8.1c.ru/8.1/data/enterprise/current-config. Соответствие префиксов пространствам имён «зашито» в платформу. Поэтому каких-либо трудностей с определениями типов при обмене между приложениями 1С:Предприятия не возникает.

А при обмене с внешними системами, для правильной десериализации типов платформы, внешней системе понадобится полная таблица соответствия. Такая таблица есть, и она опубликована в документации.

Особенности десериализации

Общие принципы десериализации также связаны с использованием механизма XDTO. В частности:

  • Десериализуются только те типы, которые поддерживают XDTO сериализацию;
  • Порядок свойств JSON должен соответствовать структуре объекта конфигурации.

При десериализации у вас есть возможность изменить получаемые данные. Для этого, как и в случае с примитивными типами и коллекциями, вы можете использовать функцию восстановления.

Эта возможность может потребоваться, например, для того, чтобы при переносе данных из одного прикладного решения в другое, заменить в них ссылки на связанные объекты. Так, чтобы после переноса эти данные ссылались уже на объекты новой базы. Или, например, для того, чтобы удалить из данных информацию, имеющую смысл только в исходной базе.

Допустим, в исходной базе описание товара хранится в HTML виде. А в вашей базе достаточно текстового описания, или такое описание вообще не нужно. Потому что у вас будет собственное описание.

Тогда, имея файл следующего содержания:

{
	"#type": "jcfg:CatalogObject.Товары",
	"#value": {
		"IsFolder": false,
		"Ref": "2d97a749-8ea9-11dc-8ca1-000d8843cd1b",
		"DeletionMark": false,
		"Parent": "87f1c226-9679-11db-a9b2-00055d49b45e",
		"Code": "000000030",
		"Description": "Колбаса",
		"Артикул": "Kol67",
		"Поставщик": "95f19911-d7c6-11db-a9bd-00055d49b45e",
		"ФайлКартинки": "00000000-0000-0000-0000-000000000000",
		"Вид": "Товар",
		"Штрихкод": "",
		"Описание":"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
			<html>
				<head>
					<meta name=\"viewport\" content=\"initial-scale=1.0, width=device-width\"></meta>
					<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>
					<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"></meta>
					<meta name=\"format-detection\" content=\"telephone=no\"></meta>
					<style type=\"text/css\">\n
						body{margin:0px;padding:8px;overflow:auto;width:100%;height:100%;}\n
						p{line-height:1.15;margin:0px;}\n
						ol,ul{margin-top:0px;margin-bottom:0px;}\n
						img{border: none;}\n
					</style>
				</head>
				<body>\n
					<p>Колбаса \"Докторская\" вареная высшего сорта из охлажденного мяса</p>\n
					<p><span style=\" font-weight: bold;\">Вес - </span> 500 г.</p>\n
				</body>
			</html>"
	}
}

вы можете при десериализации использовать собственную функцию восстановления, в которой очистить свойство Описание:

В результате этого кода будет прочитан объект СправочникОбъект.Товары, у которого реквизит Описание будет содержать пустую строку:

Теги: JSON  разработка  8.3.7