Как получить текст XML-запроса при работе с веб-сервисами и XDTO в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними системами через веб-сервисы (SOAP) часто возникает ситуация, когда "на той стороне" возникают ошибки, и разработчики внешнего сервиса просят предоставить точный текст XML-запроса, который отправляет 1С. Поскольку работа через WSПрокси скрывает внутреннюю кухню формирования SOAP-пакета, получение этого текста может стать проблемой. В этой статье мы разберем несколько эффективных способов — от простых встроенных методов платформы до использования профессиональных инструментов отладки трафика.

Метод 1. Программная сериализация объекта XDTO в XML

Самый быстрый способ увидеть структуру данных, которые вы подготовили для отправки — это использовать объект ЗаписьXML и метод фабрики XDTO ЗаписатьXML. Однако здесь есть важный нюанс: этот метод выгружает только тело (данные) вашего объекта, но не весь SOAP-конверт.

Рассмотрим, как правильно инициализировать запись, чтобы избежать ошибки "Не установлен приемник XML". Проанализируем пример кода для получения строки:


// Создаем объект записи XML
Запись = Новый ЗаписьXML;

// Важно: устанавливаем способ вывода (в строку)
Запись.УстановитьСтроку();

// Используем фабрику прокси или глобальную фабрику для записи объекта
// Параметры: ЗаписьXML, ОбъектXDTO
Прокси.ФабрикаXDTO.ЗаписатьXML(Запись, Товары);

// Получаем результат и закрываем запись
ТекстЗапроса = Запись.Закрыть();
Сообщить(ТекстЗапроса);

Если данных очень много, удобнее записывать их сразу в файл. Разберем по шагам, как это реализовать с указанием кодировки, что часто бывает критично для внешних систем:


ПутьКФайлу = ПолучитьИмяВременногоФайла("xml");
Запись = Новый ЗаписьXML;

// Открываем файл с явным указанием кодировки
Запись.ОткрытьФайл(ПутьКФайлу, "UTF-8");
Запись.ЗаписатьОбъявлениеXML();

// Записываем XDTO объект
Прокси.ФабрикаXDTO.ЗаписатьXML(Запись, Товары);

Запись.Закрыть();
// Теперь файл можно открыть любым текстовым редактором

Метод 2. Понимание разницы между XDTO и SOAP-конвертом

Выясним причину, по которой иногда ЗаписатьXML недостаточно. Когда вы вызываете метод Прокси.SetGoods(Товары), платформа 1С автоматически оборачивает ваши данные в так называемый SOAP-конверт. Он включает в себя:

Если внешняя система жалуется на ошибки в структуре самого запроса или пространствах имен (Namespaces), вам потребуется увидеть именно этот полный пакет.

Метод 3. Использование инструментов перехвата трафика (Fiddler и SoapUI)

Если вы работаете на стороне клиента или имеете доступ к серверу, отличным решением будет использование специализированного ПО. Рассмотрим два наиболее популярных инструмента:

  1. SoapUI. Позволяет импортировать WSDL вашего сервиса и сформировать "эталонный" запрос. Вы можете сравнить то, что генерирует 1С, с тем, что ожидает сервис в SoapUI.
  2. Fiddler. Это прокси-сервер, который встает "между" 1С и интернетом. Он перехватывает каждый байт. В нем вы увидите не только тело XML, но и HTTP-заголовки (Headers), такие как Content-Type, SOAPAction и данные авторизации.

Для того чтобы Fiddler "увидел" трафик 1С, иногда требуется настроить прокси в самой 1С или в файле inetcfg.xml, либо просто запустить Fiddler в режиме системного прокси.

Метод 4. Настройка Технологического журнала (ТЖ)

В ситуациях, когда установка стороннего ПО на сервер запрещена (политика безопасности), на помощь приходит Технологический журнал 1С. Это встроенный механизм, который позволяет логировать работу веб-клиентов. Для перехвата SOAP-пакетов нам нужно настроить событие WSC (Web-service client).

Создадим или отредактируем файл logcfg.xml в папке настроек 1С (обычно в conf), добавив туда следующее описание:


<config xmlns="http://v8.1c.ru/7.4/lcfm">
    <log location="C:\LOGS\WSC" history="24">
        <event>
            <eq property="Name" value="WSC"/>
        </event>
        <property name="All"/>
    </log>
</config>

После этого платформа начнет записывать все исходящие и входящие пакеты веб-сервисов в текстовые файлы логов. В них вы найдете полные дампы SOAP-сообщений. Это "тяжелая артиллерия" отладки, которая работает всегда.

Метод 5. Переход на HTTPЗапрос для полного контроля

Проанализируем ситуацию: если работа через WSПрокси остается "черным ящиком" и вы постоянно сталкиваетесь с проблемами формирования XML, опытные разработчики рекомендуют использовать HTTPСоединение и HTTPЗапрос.

В этом случае вы сами формируете текст SOAP-пакета (например, по шаблону из SoapUI) и отправляете его как обычный POST-запрос. Это дает 100% контроль над структурой XML. Посмотрим на примерную схему:


// Формируем шаблон конверта
Шаблон = 
"<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
|    <soap:Body>
|        <m:SetGoods xmlns:m=""http://www.example.com/items"">
|            %ДанныеXDTO%
|        </m:SetGoods>
|    </soap:Body>
|</soap:Envelope>";

// Подставляем туда XML, полученный из ФабрикаXDTO.ЗаписатьXML
ТекстЗапроса = СтрЗаменить(Шаблон, "%ДанныеXDTO%", ПолученныйТекстXDTO);

// Отправляем через HTTPЗапрос
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса, КодировкаТекста.UTF8);
Ответ = Соединение.ОтправитьДляОбъекта(Запрос);

Советы по отладке и логированию

При работе с внешними шлюзами (особенно платежными или государственными системами) хорошей практикой считается принудительное логирование всех запросов и ответов в файл или специальный регистр сведений в базе 1С.

Как отмечают участники обсуждения, можно использовать схему: создаем временный XML -> отправляем запрос -> при успехе удаляем файл. Если же произошла ошибка (исключение или код ответа не равен 200), файл сохраняется. Это позволяет техподдержке мгновенно увидеть, что именно ушло на сервер в момент сбоя, без необходимости повторно воспроизводить ошибку в отладчике.

Резюмируем: для быстрого просмотра структуры объекта используйте ЗаписьXML + УстановитьСтроку(). Для анализа проблем авторизации и структуры конверта используйте Fiddler или Технологический журнал. Если же требуется максимальная гибкость — формируйте запросы вручную через HTTPЗапрос.

← На главную