При интеграции с внешними сервисами через веб-сервисы и API (например, ВетИС «Меркурий») разработчики часто сталкиваются с ситуацией, когда статическую WS-ссылку невозможно добавить в дерево метаданных конфигурации. Конфигуратор выдает критическую ошибку: «набор схем не может содержать схемы с одинаковыми целевыми пространствами имен». Это происходит из-за того, что WSDL-описание сервиса или каскадно импортируемые им XSD-файлы содержат повторяющиеся пространства имен (targetNamespace).
В качестве обходного пути фабрику XDTO и определения сервиса создают динамически программным кодом. Однако при каждом обращении к удаленному URL (http://...) платформа выполняет сетевые запросы, скачивая WSDL и все зависимые XSD-схемы заново. Это приводит к задержкам от 3 до 6 секунд на каждый запрос. Попытка сохранить готовую фабрику в ХранилищеЗначения или преобразовать её через ЗначениеВСтрокуВНутр() завершается ошибкой, так как объекты ФабрикаXDTO, WSОпределения и WSПрокси в платформе 1С являются несериализуемыми.
Разберем подробнее, как обойти данные ограничения и сократить время формирования фабрики XDTO до долей секунды.
Проанализируем причину долгой инициализации: основное время уходит на сетевые HTTP/HTTPS-запросы для загрузки схем с удаленного сервера. Если мы исключим сеть и предоставим платформе схемы локально, фабрика будет инициализироваться практически мгновенно.
Разберем по шагам реализацию этого механизма:
СоздатьФабрикуXDTO().Посмотрим на пример программной реализации:
// 1. Формируем путь во временном каталоге
ИмяКаталога = ПолучитьКаталогВременныхФайлов() + "XSD_Schema_" + Строка(Новый УникальныйИдентификатор()) + "\";
СоздатьКаталог(ИмяКаталога);
ПутьКФайлуСхемы = ИмяКаталога + "SchemaXSD_Exchange.xsd";
// 2. Получаем макет и сохраняем его на диск
МакетСхемы = Обработки.ИнтеграцияСМеркурием.ПолучитьМакет("СхемаXSDОбмена");
МакетСхемы.Записать(ПутьКФайлуСхемы);
// 3. Создаем фабрику XDTO из локального файла
МояФабрикаXDTO = СоздатьФабрикуXDTO(ПутьКФайлуСхемы);
// 4. После завершения работы каталог можно очистить
УдалитьФайлы(ИмяКаталога);
Такой подход полностью устраняет зависимость от стабильности удаленного сервера при инициализации схемы и ускоряет процесс в разы.
Хотя объект ФабрикаXDTO нельзя записать в базу данных через ХранилищеЗначения, его можно хранить в оперативной памяти сервера 1С на протяжении всего сеанса пользователя.
Для этого воспользуемся механизмом общих модулей с повторным использованием возвращаемых значений:
ИнтеграцияПовтИсп.Посмотрим на пример кода в общем модуле:
Функция ПолучитьФабрикуXDTOСервиса() Экспорт
// Получаем макет с двоичными данными схемы
ДвоичныеДанныеСхемы = ОбщиеМакеты.СхемаМеркурийXSD.Получить();
ПутьКФайлу = ПолучитьИмяВременногоФайла("xsd");
ДвоичныеДанныеСхемы.Записать(ПутьКФайлу);
Фабрика = СоздатьФабрикуXDTO(ПутьКФайлу);
УдалитьФайлы(ПутьКФайлу);
Возврат Фабрика;
КонецФункции
При первом обращении к функции ИнтеграцияПовтИсп.ПолучитьФабрикуXDTOСервиса() платформа создаст фабрику и сохранит ее в памяти. При всех последующих вызовах внутри текущего сеанса 1С готовый объект будет возвращаться мгновенно (за 0 миллисекунд) без повторного чтения файлов и парсинга схем.
Если для архитектуры решения принципиально иметь строго типизированную WS-ссылку непосредственно в дереве метаданных конфигурации, можно устранить первопричину ошибки импорта:
targetNamespace.<xs:schema>.schemaLocation тегов import и include в WSDL-файле, указав локальные объединенные файлы схем.Если интеграция включает частую отправку стандартных запросов, можно полностью отказаться от тяжеловесных объектов WSПрокси и ФабрикаXDTO:
ЗаписьXML или ДокументDOM.HTTPСоединение методом POST с установкой необходимых HTTP-заголовков (SOAPAction, Content-Type: text/xml; charset=utf-8).ЧтениеXML.Это исключает любые накладные расходы платформы на инициализацию и валидацию структуры XDTO при каждом запуске операций обмена.