Интеграция с внешними веб-сервисами через протокол SOAP — стандартная задача для разработчика 1С. Однако при работе с сервисом Яндекс.Спеллер (предназначенным для проверки орфографии) начинающие специалисты часто сталкиваются с ошибкой Несоответствие типов. В этой статье мы подробно разберем, почему возникает эта проблема, как правильно работать с фабрикой XDTO и какие существуют альтернативные способы взаимодействия с сервисом.
Рассмотрим ситуацию, когда при попытке создания параметра через ФабрикаXDTO.Создать() система возвращает Неопределено или ошибку соответствия. Выясним причину: в WSDL-описании сервиса имя метода (например, checkText) часто совпадает с именем обертки запроса, но 1С не всегда может неявно сопоставить их в контексте WSПрокси.
Проанализируем типичную ошибку: разработчик пытается получить тип, используя имя метода checkText. Однако checkText — это операция веб-сервиса, а не тип данных в пакете XDTO. Именно поэтому метод Получить() возвращает Неопределено, а последующая попытка создать объект по этому типу вызывает исключение.
Самый простой и эффективный способ работы с Яндекс.Спеллером в 1С — это прямая передача параметров в метод прокси-объекта. Если веб-сервис ожидает простые типы данных (например, строку), 1С умеет самостоятельно упаковывать их в SOAP-конверт. Разберем этот пример кода:
// Создаем прокси на основании имеющейся в конфигурации WS-ссылки
Прокси = WSСсылки.Speller.СоздатьWSПрокси("http://speller.yandex.net/services/spellservice", "SpellService", "SpellServiceSoap");
// Текст, который мы хотим проверить
ТекстДляПроверки = "Проверка орфографии в этом притложении";
// Вызываем метод напрямую. 1С сама преобразует строку в нужный XML-тип
Ответ = Прокси.checkText(ТекстДляПроверки);
В данном случае нам не нужно вручную обращаться к ФабрикаXDTO, так как параметр text является строковым. Это значительно сокращает код и уменьшает вероятность ошибки в именовании типов.
Если нам необходимо программно определять структуру параметров или работать с более сложными типами данных, воспользуемся объектом WSОпределения. Это позволяет динамически анализировать состав веб-сервиса. Рассмотрим этот процесс по шагам:
WSОпределения, загружая WSDL-описание по URL.Посмотрим на пример реализации:
АдресWSDL = "https://speller.yandex.net/services/spellservice?WSDL";
Определение = Новый WSОпределения(АдресWSDL);
// Указываем URI пространства имен и имя сервиса
ПространствоИмен = "http://speller.yandex.net/services/spellservice";
ИмяСервиса = "SpellService";
ТочкаПодключения = "SpellServiceSoap";
// Создаем прокси
Прокси = Новый WSПрокси(Определение, ПространствоИмен, ИмяСервиса, ТочкаПодключения);
// Получаем операцию и тип ее первого параметра
Операция = Прокси.ТочкаПодключения.Интерфейс.Операции.Получить("checkText");
ТипПараметра = Операция.Параметры.Получить("text").Тип;
// Если нужно создать сложный объект (хотя для строки это избыточно)
ПараметрXDTO = Определение.ФабрикаXDTO.Создать(ТипПараметра, "Текст с ошипкой");
// Выполнение запроса
Результат = Прокси.checkText(ПараметрXDTO);
Иногда возникают ситуации, когда фабрика XDTO конкретного пакета не содержит нужного определения, но тип является стандартным для XML. В этом случае мы можем обратиться к стандартному пакету XMLSchema. Рассмотрим, как это сделать:
// Получаем тип string из стандартного пространства имен XMLSchema
ТипWSПараметра = Прокси.ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string");
WSПараметр = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра, "Ваш текст");
Важный момент: при использовании Прокси.ФабрикаXDTO.Пакеты.Получить(...) вы получаете доступ к типам, определенным именно в схеме Яндекс.Спеллера. Если вы ищете там тип checkText, его не будет, так как это действие (команда), а не структура данных.
При работе с методом checkText важно помнить, что он принимает не только текст, но и дополнительные настройки. Выясним, как управлять проверкой с помощью параметра options. Это целое число, которое является суммой бит-флагов:
Проанализируем ситуацию: если мы хотим одновременно игнорировать ссылки и находить повторы, нам нужно передать в параметр options значение 12 (4 + 8). В коде 1С это будет выглядеть так:
// Пример вызова с дополнительными параметрами: текст, язык, опции
// "ru" - код языка, 516 - игнорировать заглавные (512) + игнорировать URL (4)
Ответ = Прокси.checkText("Текст для проверки", "ru", 516);
Веб-сервис возвращает массив объектов. Каждая ошибка содержит позицию в тексте, само слово и список вариантов исправлений (подсказок). Проанализируем, как правильно обработать эти данные в цикле:
Если ТипЗнч(Ответ) = Тип("ОбъектXDTO") Или ТипЗнч(Ответ) = Тип("СписокXDTO") Тогда
// Если ошибок много, придет СписокXDTO, если одна - ОбъектXDTO
// Для универсальности можно использовать проверку количества
Для Каждого Ошибка Из Ответ Цикл
Сообщить("Найдена ошибка в слове: " + Ошибка.word);
Для Каждого Вариант Из Ошибка.s Цикл
Сообщить("Возможно вы имели в виду: " + Вариант);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Работа через SOAP (WS-ссылки) в 1С иногда бывает громоздкой из-за строгой типизации XDTO. Яндекс.Спеллер поддерживает более современный интерфейс JSON через обычные HTTP-запросы. Рассмотрим этот способ как альтернативу, которая часто работает быстрее и стабильнее:
Соединение = Новый HTTPСоединение("speller.yandex.net", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос("/services/spellservice.json/checkText");
Запрос.УстановитьТелоИзСтроки("text=" + КодироватьСтроку("Текст с ошипкой", СпособКодированияСтроки.URLВКодировкеURL) + "&lang=ru");
Ответ = Соединение.ОтправитьДляОбъекта(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоИзСтроки());
МассивОшибок = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Обрабатываем массив структур
КонецЕсли;
Резюмируем: при возникновении ошибки Несоответствие типов первым делом проверьте, не пытаетесь ли вы использовать имя метода вместо имени типа XDTO. Для простых запросов к Яндекс.Спеллеру лучше использовать прямую передачу параметров в WSПрокси или перейти на HTTPСоединение с форматом JSON, что избавит от необходимости настройки XDTO-пакетов.