Qt

KDSoap + Qt5 пример написания SOAP клиента

Надеюсь сборка прошла гладко =) теперь небольшой пример использования SOAP протокола =)

Для начала определимся с каким сервисом будем работать.  Для примера я предлагаю получить курс валюты на определённую дату от ЦентроБанка

Страничка сервиса и доступные методы и сам  wsdl файл

В QtCreator создаём новый проект на Ваше усмотрение.

В *.pro файле дописываем:

LIBS += -LC:/Projects/kdsoap/lib -lkdsoapd1
QT += network core
INCLUDEPATH += C:/Projects/kdsoap/include

Скачиваем wsdl файл и кидаем его в корень директории своего проекта, у меня файл назван DailyInfo.wsdl

Дальше нужно сгенерировать классы для работы с soap из wsdl файла, для этого служит утилита kdwsdl2cpp.exe из каталога C:\Projects\kdsoap\bin

Открываем консольку и переходим в  корневую папку проекта (у меня C:\Projects\1CTerminal\1CTerminal\)
и генерируем файлы:

cd C:\Projects\1CTerminal\1CTerminal\
C:\Projects\kdsoap\bin\kdwsdl2cpp.exe  -o dailyinfo.h dailyinfo.wsdl
C:\Projects\kdsoap\bin\kdwsdl2cpp.exe -impl dailyinfo.h -o dailyinfo.cpp dailyinfo.wsdl
[tip] Скорее всего понадобиться добавить пути  в Path:
set PATH=C:\Qt\Qt5.2.1\5.2.1\mingw48_32\bin;%PATH%
[/tip]

dailyinfo.h — сгенерированный заголовочный файл для работы с dailyinfo.wsdl
и соответственно dailyinfo.cpp — реализация.
Не забудьте — при изменение wsdl файла описания сервиса нужно заново пересобирать эти классы!

[tip] Можно сделать автогенерацию классов при компиляции, для этого в *.pro файле:
KDWSDL = dailyinfo.wsdl 
WSDL_DIR = generated //-- Путь, куда складывать сгенерированные файлы
KDSOAPDIR = C:\Projects\kdsoap
include(kdsoap.pri)

А также в корень проекта кинуть сам kdsoap.pri из папки с kdsoap.
Также тогда потребуется убрать добавление библиотеки из  LIBS  и INCLUDEPATH
Кстати, так же нужно будет сгенерить дебажную и релизную версии kdsoap
Ну и проверить в kdsoap.pri правильно ли называются сами библиотеки.
[/tip]

Работа KDSoap основана на механизме сигнал-слотов.

Нас интересует пока что метод GetCursOnDate (описание методов тут или тут)

Открываем dailyinfo.h  и в самом начале видим основное пространство имён (DailyInfo) а так же основной класс (DailyInfoSoap12), через который мы будем вызывать методы сервиса.
Сигналы обычно именуются следующим образом:

об успешном выполнении getCursOnDateDone
об ошибке: getCursOnDateError.
Что бы узнать какие нужны параметры для вызова метода ищем поиском объявление функции «getCursOnDate(«.

В данном случае параметром будет  const TNS__GetCursOnDate& parameters,
аналогично ищем для сигналов getCursOnDateDone  и getCursOnDateError.
Кстати, QtCreator сам подскажет какие, если что 😉

Создадим вспомогательный класс, например  SoapClient, наследуемся от QObject.

#ifndef SOAPCLIENT_H
#define SOAPCLIENT_H
#include <QObject>
#include <QDebug>

//-- Подключаем сгенерированный класс.
//-- Если Вы классы для wsdl генерируете из qmake, то называться будет wsdl_dailyinfo.h
#include "wsdl_DailyInfo.h"
using namespace DailyInfo;
class SoapClient : public QObject
{
Q_OBJECT
public:
   explicit SoapClient(QObject *parent = 0);

signals:

public slots:

private slots:
   void onGetCursOnDateDone(const TNS__GetCursOnDateResponse& parameters); //-- успешное выполнение метода, принимаем результат
   void onGetCursOnDateError(const KDSoapMessage& fault); //-- Ошибка
private:
    DailyInfoSoap * dailyInfo;

};
#endif // SOAPCLIENT_H

Реализаци

#include "soapclient.h"

SoapClient::SoapClient(QObject *parent) : QObject(parent)

{

   dailyInfo = new DailyInfoSoap(this); //-- Новый объект для работы с сервисом
   dailyInfo->setEndPoint(QLatin1String("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx")); //-- Адрес сервиса
   dailyInfo->setSoapVersion(KDSoapClientInterface::SOAP1_2); //-- Протокол

   //-- Коннектим сигналы со слотами
   connect(dailyInfo, &DailyInfoSoap::getCursOnDateError, this, &SoapClient::onGetCursOnDateError);
   connect(dailyInfo, &DailyInfoSoap::getCursOnDateDone, this, &SoapClient::onGetCursOnDateDone);

   //-- Парметры для вызова метода GetCursOnDate
   TNS__GetCursOnDate params;
   KDDateTime data = KDDateTime::currentDateTime(); //-- не долго мучаясь поставим текущую
   params.setOn_date(data);

   dailyInfo->asyncGetCursOnDate(params);

}

void SoapClient::onGetCursOnDateDone(const TNS__GetCursOnDateResponse& parameters) {

   qDebug()<<"Done!!!";

   TNS__GetCursOnDateResult res= parameters.getCursOnDateResult();

   qDebug()<<res.any().toXml(); //-- Из вывода узнаём как нам путешествовать, что бы найти необходимые данные

   KDSoapValue diffgram=res.any();
   KDSoapValue valuteData=res.any().childValues().at(0);
   KDSoapValue usaDollar= valuteData.childValues().at(10);

   QList<KDSoapValue> atributes= usaDollar.childValues().attributes();

   qDebug()<<"id"<<atributes.at(0).value().toString();
   qDebug()<<"rowOrder"<<atributes.at(1).value().toString();
   qDebug()<<"Vname"<<usaDollar.childValues().at(0).value().toString();
   qDebug()<<"Vnom"<<usaDollar.childValues().at(1).value().toString();
   qDebug()<<"Vcurs"<<usaDollar.childValues().at(2).value().toString();
   qDebug()<<"Vcode"<<usaDollar.childValues().at(3).value().toString();
   qDebug()<<"VchCode"<<usaDollar.childValues().at(4).value().toString();
   qDebug()<<"Статья написана pavelk.ru, надеюсь было понятно=)";

}

void SoapClient::onGetCursOnDateError(const KDSoapMessage& fault)
{
   qDebug()<<"Error!";
}

Дальше в main.cpp не забудем подключить и создать класс:

#include "soapclient.h"
SoapClient * client = new SoapClient(0);

Запускаем и смотрим вывод =)

Надеюсь всё заработало и стало теперь понятно как написать SOAP клиент на Qt5.

Related posts

QML Сделать задержку перед началом анимации

QtCreator не открывает диалог выбора файлов, проектов, не открывает проект

Сборка Qt 6.8 (Dev) из исходников в Docker контейнере (Linux)