QT5.9.4/VS2015 + gsoap 实现访问webService功能

前言:因工作需要用到webService,在网上百度了一下实现方案,主要分两种——QtSoap和gsoap,考虑到QtSoap也是第三方服务(Qt本身不提供这个模块),于是选择使用QT + gsoap实现对webService的访问。然而,实际操作的时候遇到了不少问题,使用网上的demo并不能顺利地编译和运行,并且编译报错内容看的自己有点懵逼,恰巧看到有两篇介绍VS+gsoap的方案,感觉比较靠谱,就先用VS2015编译了一下,发现可以运行,所以本文将使用VS和Qt的方法都记录了下来。

备注(电脑系统和软件版本):win10系统,VS2015,QT5.9.4。

一、下载gsoap压缩包并解压:

1. 2.8.67版本下载地址:https://sourceforge.net/projects/gsoap2/files/

2. 下载的压缩包无需安装,下载完成后解压到任意位置(当然,路径最好不要包含中文,我是直接解压到D盘的),然后添加环境变量,因为gsoap需要用到cmd和shell命令。

3. 备注:

1)不清楚什么原因,该链接下载速度很慢,我第一次下载后解压提示压缩包损坏,第二次下载的才能正常使用;

2)添加环境变量后,Shift加鼠标右键可以直接打开Powershell窗口,之前是cmd控制台窗口。添加环境变量截图如下:

二、通过VS2015 + gsoap创建webService服务端和客户端:

1. 开发自己的服务端和客户端可以参考两篇博客,这里附上链接,基本上按照博客指导可以完成服务端创建和客户端的运行。

服务端:https://blog.csdn.net/testcs_dn/article/details/51463367

客户端:https://blog.csdn.net/testcs_dn/article/details/51526051

2. 这里记录一下实际操作的几个步骤,里面主要是一些不同于上面链接的操作:

1)创建服务端:进入解压后的文件夹目录D:\gsoap-2.8\gsoap\bin\win32下,可以看到两个exe文件。

编写接口文件itoa.h,在当前目录下运行shell命令: soapcpp2 -S itoa.h ,会生成好几个文件,更新后的目录如下:

VS2015中新建工程,参考上面的链接替换itoaServer.cpp文件,在代码中替换两个语句,不然构建时会报错,方法如下:

运行服务端程序,将itoa.wsdl文件拷贝到debug目录下,shell命令行输入 .\itoaServer.exe 8087,在浏览器中打开对应网址,可以正常显示则服务端程序创建成功。

 

2)建立客户端:

运行之前创建的服务端程序,回到D:\gsoap-2.8\gsoap\bin\win32下,删除之前生成的文件,shell命令行输入 wsdl2h -o itoa.h http://localhost:8087/itoa?Wsdl,会生成itoa.h文件,继续输入 soapcpp2 -j itoa.h,会生成代理类和相关文件。参照链接中的指导,在VS2015中新建客户端工程,编译并运行即可。

3)这里附上服务端和客户端各自用到的文件和目录系统:

      

三、Qt5.9.4实现webService访问功能:

 1. 访问上面创建的个人服务端:

1)通过gsoap生成代理类和相关文件,操作和上面相同;

2)Qt新建gui工程,导入相关文件,pro文件如下:

 1 QT += gui widgets
 2 
 3 CONFIG += c++11
 4 #CONFIG +=  console
 5 
 6 CONFIG -= app_bundle
 7 
 8 DEFINES += QT_DEPRECATED_WARNINGS
 9 
10 SOURCES += main.cpp \
11     soapC.cpp \
12     soapitoaProxy.cpp \
13     stdsoap2.cpp \
14     dialog.cpp
15 
16 HEADERS += \
17 #    itoa.nsmap \
18     soapitoaProxy.h \
19     stdsoap2.h \
20     soapH.h \
21     soapStub.h \
22     dialog.h
23 
24 FORMS += \
25     dialog.ui

3)ui布局:

(4)编写槽函数:

void Dialog::on_pushButton_clicked()
{
    itoaProxy service;

    double a, b;
    a = ui->lineEdit_a->text().toDouble();
    b = ui->lineEdit_b->text().toDouble();

    int connect_result;
    double add_res;
    connect_result = service.add( a, b, add_res );

    qDebug( "%d  %f", connect_result, add_res );
    ui->lineEdit_addresult->setText( QString("%1").arg( add_res, 0, 'f', 2 ) );
}

5)注意事项:

导入相关文件后,直接编译会报错,截图如下:

错误原因是结构体重复定义,修改方法分三步:

  • 注释部分代码:

 

  • itoa.nsmap文件的部分代码拷贝到soapitoaProxy.cpp中:

  • 注释itoa.nsmap头文件包含:

 

2. 访问已有的webService服务,以qq在线检测检测为例:

1)web服务网址:http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl

2)生成qqCheckOnline.h头文件:

D:\gsoap-2.8\gsoap\bin\win32目录下运行shell命令,输入

wsdl2h -o qqCheckOnline.h http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl

(3)生成代理文件:

从D:\gsoap-2.8\gsoap\import目录下拷贝soap12.h文件,输入shell命令

soapcpp2 -j .\qqCheckOnline.h ,新的目录如下:

 

(4)Qt中新建gui工程,导入相关文件:

 1 QT       += core gui
 2 
 3 CONFIG += c++11
 4 CONFIG += console
 5 
 6 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 7 
 8 TARGET   = qqCheckOnline
 9 TEMPLATE = app
10 
11 DEFINES += QT_DEPRECATED_WARNINGS
12 
13 SOURCES += \
14     main.cpp \
15     dialog.cpp \
16     gsoap/soapC.cpp \
17     gsoap/soapqqOnlineWebServiceSoapProxy.cpp \
18     gsoap/stdsoap2.cpp
19 
20 HEADERS += \
21     dialog.h \
22 #    gsoap/qqOnlineWebServiceSoap.nsmap \
23     gsoap/soap12.h \
24     gsoap/soapH.h \
25     gsoap/soapqqOnlineWebServiceSoapProxy.h \
26     gsoap/soapStub.h \
27     gsoap/stdsoap2.h
28 
29 FORMS += \
30     dialog.ui

5)ui布局和槽函数编写:

 

void Dialog::on_pushButton_clicked()
{
    int     connect_reult;
    std::string str_number, *str_state;
    str_number = ui->lineEdit_qq_number->text().toStdString();

    qqOnlineWebServiceSoapProxy     service;    //使用代理类创建服务
    _ns1__qqCheckOnline             request;    //函数调用需要的参数(包含qq号码)
    _ns1__qqCheckOnlineResponse     response;   //函数调用需要的参数(包含在线状态)

    qDebug( "%d", 111111 );
    request.qqCode = &str_number;
    qDebug() << request.qqCode;

    connect_reult = service.qqCheckOnline( &request, response );
    str_state     = response.qqCheckOnlineResult;

    if( SOAP_OK != connect_reult )
    {
        ui->lineEdit_qq_state->setText("soap连接失败");
        return;
    }

    QString state = QString::fromStdString( *str_state );

    if(state == "Y")
    {
        ui->lineEdit_qq_state->setText("在线");
    }
    else if(state == "N")
    {
        ui->lineEdit_qq_state->setText("离线");
    }
    else if(state == "E")
    {
        ui->lineEdit_qq_state->setText("QQ号码错误");
    }
    else if(state == "A")
    {
        ui->lineEdit_qq_state->setText("商业用户验证失败");
    }
    else if(state == "V")
    {
        ui->lineEdit_qq_state->setText("免费用户超过数量");
    }
    else
    {
        ui->lineEdit_qq_state->setText("未知错误");
    }
}

6)注释和拷贝gsoap/qqOnlineWebServiceSoap.nsmap的部分代码到soapqqOnlineWebServiceSoapProxy.cpp文件中:

7)编译和运行结果图。

  

  

这个111111111111显示离线我是不信的,应该还没有12位的号吧,手动滑稽。

备注:如果编译或运行有别的问题,也可以一起讨论一下。ps:代码并不复杂,如果想要工程源码,可以私聊我。

 

猜你喜欢

转载自www.cnblogs.com/wyjajt/p/9234784.html