DIRECTUM и WEB-сервисы (часть 2)

17 23

В предыдущем материале мы рассмотрели, как можно обращаться к WEB-сервисам из DIRECTUM на примере простого сервиса склонения «Морфер». Рассмотрим более сложный пример, в котором обратимся к WEB-сервису Центрального банка Российской Федерации.

Описание доступных методов можно посмотреть по адресу: http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx.

Описание самого WEB-сервиса находится по адресу: http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx?WSDL.

Возьмем для примера метод:

  • GetCursOnDateXML - Получение ежедневных курсов валют (как XMLDocument). Методу нужно передать дату, на которую нас интересует состояние курсов валют.

Пример работы с данным WEB-сервисом:

  WSDLFileName = "http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx?WSDL"

  // Инициализация подключения к сервису
  SoapClient = CreateObject("MSSOAP.SoapClient30")
  SoapClient.MSSoapInit(WSDLFileName)
  
  Rez = SoapClient.GetCursOnDateXML(Сейчас())
  Окно(Rez)

В результате получим следующее сообщение: 

Как видно результат нам ничего не дал, что вполне ожидаемо, т.к. результат должен быть XMLDocument. 

Разобраться в ситуации нам поможет Microsoft SOAP Toolkit 3.0, который можно бесплатно скачать с сайта Microsoft по адресу: http://www.microsoft.com/downloads/en/details.aspx?FamilyId=C943C0DD-CEEC-4088-9753-86F052EC8450&displaylang=en

SOAP Toolkit включает в себя следующие части:

  • SOAP Listener – серверные компоненты, предназначенные для обработки входящих запросов. Представлены в 2-х разновидностях – ASP-страница и ISAPI-расширение.
  • Proxy – клиентский компонент, позволяющий преобразовать вызов метода, осуществляемый через IDispatch-интерфейс, в SOAP-вызов.
  • Утилита для трассировки SOAP-вызовов, позволяет перехватывать вызовы к серверу и анализировать запросы и ответы сервера.
  • WSDL-генератор. По библиотеке типов компонента генерирует файлы, необходимые для работы SOAP Listener’а и Proxy. В этих файлах находятся описания методов, параметров, типов параметров и т.д.
  • Набор низкоуровневых компонентов, предназначенных для создания SOAP-запросов, преобразования различных типов данных в текстовый формат, приема и передачи пакетов по протоколу HTTP и преобразования ответа сервера.
  • Документация и примеры.

Для того, чтобы разобраться с ответом, который пришел от WEB-сервиса воспользуемся утилитой для трассировки SOAP-вызовов MsSoapT3.exe. Подключим утилиту для анализа ответа WEB-сервиса:

  1. Сохраняем описание WEB-сервиса (http://www.cbr.ru/dailyinfowebserv/dailyinfo.asmx?WSDL) на локальный диск, например, с именем dailyinfo.wsdl (я положил его сюда: D:\Temp\dailyinfo.wsdl);
  2. Открываем блокнотом dailyinfo.wsdl и ищем в нем элемент "". В нашем случае эта строка будет выглядеть так: ""
  3. Отмечаем для себя два параметра:
    • HostName = www.cbr.ru
    • Port = 80 (если бы строка выглядела, например, так: "", то Port = 8000)
  4. Приводим эту строку к следующему виду: ""
  5. Запускаем MsSoapT3.exe из состава MicrosoftSOAPToolkit 3.0, выбираем пункт меню File\New\FormattedTrace и вводим два запомненных ранее параметра: 

 

       где Destination host = HostName, а Destination port = Port. После чего жмем «ОК».

    6. Модифицируем наш пример и приведем его к следующему виду:

  WSDLFileName = "D:\Temp\dailyinfo.wsdl"

  // Инициализация подключения к сервису
  SoapClient = CreateObject("MSSOAP.SoapClient30")
  SoapClient.MSSoapInit(WSDLFileName)

  Rez = SoapClient.GetCursOnDateXML(Сейчас())
  Окно(Rez) 

    7. Запускаем сценарий и в окне MsSoapT наблюдаем следующую картину:

В правом верхнем окне мы видим запрос, который мы отправили WEB-сервису, а в правом нижнем окне ответ, полученный от сервиса. Теперь разобраться с ответом не составит труда. Например, вот так:

  WSDLFileName = "D:\Temp\dailyinfo.wsdl"

  // Инициализация подключения к сервису
  SoapClient = CreateObject("MSSOAP.SoapClient30")
  SoapClient.MSSoapInit(WSDLFileName)
  
  Rez = SoapClient.GetCursOnDateXML(Сейчас())
  
  // Получим дату курсов валют
  ValuteData = Rez.Item(0)
  OnDate = ValuteData.Attributes.getNamedItem("OnDate").Value
  Year = Copy(OnDate;1;4)
  Month = Copy(OnDate;5;2)
  Day = Copy(OnDate;7;2)
  Data = Format("%s.%s.%s";ArrayOf(Day;Month;Year))
  Str = "Курсы валют на "&Data&" составляют:"&CR
  // Получим дочерние элементы
  ChildNodes = ValuteData.childNodes
  // Количество дочерних элементов
  ChildNodesCount = ChildNodes.Length
  Count = 0
  // переберем все дочерние элементы и сформируем результирующую строку
  while Count < ChildNodesCount
    Node = ChildNodes.Item(Count)
    NodeCurs = Node.childNodes
    NodeCursCount = NodeCurs.Length
    ChildCount = 0
    Str2 = ""
    while ChildCount < NodeCursCount
      if NodeCurs.Item(ChildCount).nodeName == 'Vname'
        Vname = Trim(NodeCurs.Item(ChildCount).Text)
      endif
      if NodeCurs.Item(ChildCount).nodeName == 'Vnom'
        Vnom = NodeCurs.Item(ChildCount).Text
      endif
      if NodeCurs.Item(ChildCount).nodeName == 'Vcurs'
        Vcurs = NodeCurs.Item(ChildCount).Text
      endif
      if NodeCurs.Item(ChildCount).nodeName == 'VchCode'
        VchCode = NodeCurs.Item(ChildCount).Text
      endif
      ChildCount = ChildCount + 1
    endwhile
    Str2 = Format("%s: %s руб = %s %s";ArrayOf(Vname; Vcurs; Vnom; VchCode))
    Str = Str & Str2 & CR
    Count = Count + 1
  endwhile
  ShowMessage(Str)

В результате получаем следующее:

 

Андрей Посаженников

Эх, все таки MSSOAP классная штука. С некоторыми ограничениями на стандарты WS-*, но все же. Как жаль что MS больше его не поддерживает. И достойного аналога не предоставляет.

Виктор Золотов

А как же WCF? 

Андрей Подкин

А как же WCF? 

Я что-тот пропустил и WCF стало можно нормально использовать из скриптовых языков?
Андрей Посаженников
Я что-тот пропустил и WCF стало можно нормально использовать из скриптовых языков?

Поясни, что значит использовать?
Если имеешь в виду вызов метода сервиса, то почему бы и нет? Интероперабельность веб-сервисов как раз таки подразумевает возможность вызова из любого окружения.
Если ты имеешь в виду работу с клиентский инфраструктурой WCF, то опять же, почему бы и не вызвать. Если этот скриптовый язык поддерживает вызов COM, то можно опубликовать сборку с клиентским проксиком как COM и вызвать из скриптового языка.
Да и вся статья посвящена как раз вызову сервиса из скриптового языка :)
Виктор Золотов
Я что-тот пропустил и WCF стало можно нормально использовать из скриптовых языков?
Сам не пробовал, но чувствую тип HTTP Basiс в EndPoint как раз и позволить обращаться через в HTTP/SOAP 1.2. 
Андрей Подкин

Поясни, что значит использовать?
То и значит. Заменить MS SOAP на WCF. На клиенте. Прокси и прочее - это очень частное решение, когда речь идет о VBS или ISBL.
Получается, что альтернатив неподдерживаемому более продукту просто нет.
 
А то, что через MS SOAP можно ходить к сервисам WCF, понятно. DIRECTUM так ходит к DCTS.
Виктор Золотов
Прокси и прочее - это очень частное решение, когда речь идет о VBS или ISBL.

Не дайте умереть в незнании ), поясните в чем собственно проблема? Почему к сервису WCF нельзя обратиться из кода ISBL? Или я не правильно понял названную проблематику?
Андрей Подкин

Почему к сервису WCF нельзя обратиться из кода ISBL?
Потому что ISBL не поддерживает работу с веб-сервисами.
Если вы считаете иначе, напишите пример работы с WCF-сервисом (например, DCTS) БЕЗ использования MS SOAP и других прокси.
 
Или я не правильно понял названную проблематику?
А как вы ее поняли?
Виктор Золотов

Теперь понял, спасибо.

Андрей Посаженников

В одном из блогов Наталия Ефимцева писала об интероперабельности WCF. Я попытался поднять тему MS SOAP. Похоже что вразумительного ответа на вопрос "Что использовать вместо MSSOAP?"  в MS не знают (или же просто об этом не особо задумывались). 

Либо же тренд как раз на предметную ориентированность и кодогенерацию. Если написал сервис и хочешь его поддерживать из приложений через COM, то делай этот самый клиентский COM, например на С++ (вроде бы были средства для кодогенерации проксиков и тут). 

Андрей Посаженников

Забыл ссыль на этот самый блог

Андрей Подкин

Либо же тренд как раз на предметную ориентированность и кодогенерацию.
Они просто уже совсем переехали в .NET и считают, что скриптовые языки надо использовать аналогичные (PowerShell вместо VBS, IronPython вместо CPython/ActivePython и т.д.).
Илья Чечиль

Добрый день!

В статье видимо текст ссылок не вставился, поэтому поясню, что для трассировки необходимо в файле dailyinfo.wsdl заменить строчки :

на

и строку

на 

Илья Чечиль

Добрый день!

В статье видимо текст ссылок не вставился, поэтому поясню, что для трассировки необходимо в файле dailyinfo.wsdl заменить строчки :

на

и строку

на

Дмитрий Тарасов

Илья, все верно. К сожалению в комментариях строки, содержащие xml, тоже не отображаются.

Илья Чечиль

Извиняюсь, не получилось вставить.

В статье видимо текст ссылок не вставился, поэтому поясню, что для трассировки необходимо в файле dailyinfo.wsdl заменить строчки :

soap:address location="http://cbr.ru/dailyinfowebserv/dailyinfo.asmx"

на

soap:address location="http://localhost:8080/dailyinfowebserv/dailyinfo.asmx"

и строку

soap12:address location="http://cbr.ru/dailyinfowebserv/dailyinfo.asmx"

на

soap12:address location="http://localhost:8080/dailyinfowebserv/dailyinfo.asmx"

Павел Логинов

Попробовал первый пример получил ошибку :

Что я делаю не так?
Крашится на строке: 
  SoapClient.MSSoapInit(WSDLFileName)

Дмитрий Тарасов

Я вам в первой статье еще ответил, что нужно установить Microsoft SOAP Toolkit 3.0.

Анатолий Придыбайло

Дмитрий, может подскажите как передать xml файл через SOAP, а то никак не могу с этим разобраться на сервисе http://npchk.nalog.ru/

Дмитрий Тарасов
Дмитрий, может подскажите как передать xml файл через SOAP, а то никак не могу с этим разобраться на сервисе http://npchk.nalog.ru/

Обычно, для этих целей, я использую способ описанный в примере 3-ей статьи: DIRECTUM и WEB-сервисы (часть 3)

Авторизуйтесь, чтобы написать комментарий