c++通过gsop调用基于https的webservice接口总结

news2024/11/23 20:48:49

ww哦步骤:

第一步:生成头文件

webservice接口一般会有一个对外接口文档。比如:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

问号后面的参数表示WSDL文档,是一个XML文档,看不懂配置没关系,接下来我们要通过这个文档生成c++头文件。

(1) 下载gsoap工具

下载连接:gSOAP Toolkit download | SourceForge.net

 下载完成之后解压,进入gsoap\bin\win32目录下,该目录下有两个文件wsdl2h.exe和soapcpp2.exe。wsdl2h.exe用来生成头文件。光生成头文件是不够的,这个时候要用soapcpp2.exe来生成对应的c++文件结构,可以用于项目中调用(第二步介绍)。先来看看怎么生成头文件。

 在gsoap\bin\win32目录下打开cmd命令。输入:

wsdl2h.exe -o head.h http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

 执行完成之后可以看到当前目录下多了一个head.h的头文件。可以打开看看,里面都是一些接口函数。

 注意:由webservice在传输过程中默认使用UTF-8编码,当然gsoap在生成头文件的时候默认也是窄字符。比如string或者char*。此时如果再调用过程中参数有中文就会乱码。解决方案有两个。

方法一:在后面调用的时候在代码中加一句(具体加在哪里后面介绍):

soap_set_mode(&m_soap, SOAP_C_UTFSTRING);

 方法二:由于默认使用根目录下的typemap.dat进行编译成窄字符。此时我们不适用它,而是在当前目录下新建一个mytypemap.dat。内容如下:xsd__string = | std::wstring | wchar_t* 。然后重新执行cmd命令。

wdsl2h.exe -o head.h -t mytypemap.dat http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

 重新生成之后可以发现head.h中字符串类型都变成了wchar_t * 或者wstring类型。

第二步:生成可调用API

在当前目录下执行cmd命令:

soapcpp2.exe -C -x -I ..\..\import head.h

  

其中-C是只生成客户端代码。-x表示不生成xml(我们只需要c++代码)-I 是指定import目录。
执行成功之后,当前目录下多了一些文件:

 第三步:导入到项目
将上面图片中红色框中的文件添加到你的项目中。另外还有需要添加两个文件。gsoap根目录下的stdsoap2.h和stdsoap2.cpp也需要添加到项目中。
对添加进去的3个cpp文件右击->属性->所有配置->c/c+±>预编译头,选择不使用预编译头。如下如所示。

配置完成之后,就可以开始写代码了。

第四步:编写代码

新建一个基于MFC应用程序工程,名称为:soapTest 

新建一个soapTestDlg.cpp,引入头文件

#include "WeatherWebServiceSoap.nsmap"
#include "soap.h"

我在项目中引用这两个头文件的时候,编译疯狂报错。仔细检查看了下,全是冲定义,原因是头文件 WeatherWebServiceSoap.nsmap中命名空间和项目中原有的socket库冲突了,解决方法是将#include "WeatherWebServiceSoap.nsmap"写到最前面,如果使用了预编译头,最好写在 stdafx.h文件中。头文件引入之后,再次编译,不报错了。如果不添加预编译头,则需要设置soapC.cpp、soapClientLib.cpp、soapClient.cpp、stdsoap2.cpp为不使用预编译头。


在soapClient.cpp中可以看到服务的所有接口。函数名是soap_call __ns1_XXX形式。
首先创建soap对象并初始化:

struct soap m_soap;
//SOAP初始化
soap_init(&m_soap);
soap_set_mode(&m_oSoap, SOAP_C_UTFSTRING);

其中soap_set_mode(&m_oSoap, SOAP_C_UTFSTRING);正是一开始说的为了适配中文字符。如果一开始使用了wstring或者wchar_t * 则可以忽略。然后定义reqXml字符串,调用接口函数。xml字符串中双引号需要转义。

char* _reqXml = "<root>.....</root>";
char* _Return;
soap_call_ns1__XXX(&m_soap, NULL, NULL, G2U(_reqXml), _Return);
string ret = U2G(_Return);

由于上面代码中使用的是窄字符作为参数,即char *,需要转换成UTF-8格式。具体函数如下:

char* U2G(const char* utf8)
{
	int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
	len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}

char* G2U(const char* gb2312)
{
	int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}

此时编译应该可以通过了。但是,现实是残酷的。返回的_Return值为NULL,说明出错了。我的地址是https的,如果,我直接用http请求的话会返回301,查找资料说301表示重定向,意思是这里不能像浏览器那样地址栏输入http,浏览器会帮你重定向到https。此时还是得改成https。再次编译。 额~还是报错。。。错误码可以在调试期间,查看m_soap结构体中error字段的值,如果一直是0,说明没问题。具体错误代码可以上网查一下。
改成https再调试可以看到m_soap->error的值是30,查看文档,发现30代表没有进行SSL安全认证。好吧~
在soap_init(&m_soap)后面添加如下代码:

soap_ssl_init();
if (soap_ssl_server_context(&m_soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
	soap_print_fault(&m_soap, stderr);
	exit(-1);
}

其中soap_ssl_server_context参数中如果有SSL证书,和密码就填进去。没有全NULL就完事儿。
再次编译,还是无法通过~检查代码,发现在stdsoap2.h头文件中WITH_OPENSSL没有定义。下面是灰色的。

 解决方法:右击项目属性->C/C+±>预处理器->预处理器定义中添加WITH_OPENSSL

 添加之后,发现灰色没有了

 编译之后再次报错,错误信息是soap_ssl_server_context函数无法解析的外部符号。

原因

        该函数的实现没有定义。忘记引入openssl库了。下载地址:https://slproweb.com/products/Win32OpenSSL.html

下载完成,安装,安装完成目录。

 接着在vs中右击项目->属性->配置属性->VC++目录中包含目录和库目录添加进去,如下图。

 在vs中右击项目->属性->配置属性->链接库->输入->附加依赖库项中把libcrypto.lib和libssl.lib添加进去,如下图

文件结构

 注意:

如果报xx已经在 soapClient.obj 中定义的错误,如下图

 解决方法:

        把soapClientLib.cpp的全部注释掉,再次编译即可

 以下是gsoap+opensll工具

https://download.csdn.net/download/my_angle2016/88220982

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/888034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UglifyJS 和JShaman相比有什么不同?都可以进行js混淆加密吗?

UglifyJS 和JShaman相比有什么不同&#xff1f; UglifyJS主要功能是压缩JS代码&#xff0c;减小代码体积&#xff1b;JShaman是专门用于对JS代码混淆加密&#xff0c;目的是让JS代码变的不可读、混淆功能逻辑、加密代码中的隐秘数据或字符&#xff0c;是用于代码保护的。 因此…

linux两台服务器互相备份文件(sshpass + crontab)

crontab crontab是linux系统自带的定时调度软件&#xff0c;可用于设置周期性被执行的指令&#xff0c;一般用在每天的非高峰负荷时间段运行作业&#xff0c;可在无需人工干预的情况下运行作业。支持在一周或一月中的不同时段运行。 crontab命令允许用户提交、编辑或删除相应的…

【HBZ分享】java中的BitSet 与 Redis中的BitMap 与 布隆过滤器

BitMap的存储原理 bitMap他会标识出某个整数是否存在&#xff0c;存在即为1&#xff0c;不存在对应位即为0bitMap是存储int类型的&#xff0c;int 4byte&#xff0c; 1byte 8bit&#xff0c;因此bitMap数组中的每个下标可以标识出32个数字是否存在bitMap相当于一个个小格子&…

【数据结构】二叉树的链式结构的实现 -- 详解

一、前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。为了降低大家学习成本&#xff0c;此处手动快速创建一棵简单的二叉树&#xff0c;快速进入二叉树操作学习。 typedef char BTDataType;typedef struct Binar…

管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——模态——-句式转换+性质

文章目录 第三节 模态命题-句式转换性质题-模态命题-句式转换性质-句式转换-逻辑转换&#xff1a;①不一定不可能&#xff1b;②不一定可能不未必。句式转换-语文转换&#xff1a;①一定不可能不必然&#xff1b;②一定不不可能必然不。性质-两命题间的关系-包含&#xff1a;①…

c语言——计算两个数的乘积

//计算两个数的乘积 #include<stdio.h> #include<stdlib.h> int main() {double firstNumber,secondNumber,product;printf("两个浮点数&#xff1a;");scanf("%lf,%lf",&firstNumber,&secondNumber);productfirstNumber*secondNumber…

shell scripts 学习记录

shell scripts 学习记录 1. 环境变量的使用2. Shell中的数组使用Array关联数组 (理解为python中的字典) 3. shell中的基本运算符4. shell 中流程控制语法case...esac使用 5. 函数定义与调用5.1 带返回值的函数5.2 带传参数的函数 6. shell 中的输入/输出重定向6.1 输出重定向6.…

糖尿病视网膜病变,黄斑病变,年龄相关检测研究(Matlab代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

sCrypt于8月12日在上海亮相BSV数字未来论坛

2023年8月12日&#xff0c;由上海可一澈科技有限公司&#xff08;以下简称“可一科技”&#xff09;、 临港国际科创研究院发起&#xff0c;携手美国sCrypt公司、福州博泉网络科技有限公司、复旦大学区块链协会&#xff0c;举办的BSV数字未来论坛在中国上海成功落下帷幕。 本次…

好消息!多地明确鼓励提取公积金作首付

大家好&#xff01; 我是老洪&#xff0c;看到一则公积金资讯&#xff0c;聊两句。 据媒体报道&#xff0c;多地明确鼓励提取公积金作首付。 我个人觉得鼓励提取公积金作首付&#xff0c;对于购房者来说挺好的。 这种做法不仅可以减轻首付资金压力&#xff0c;还可以提高购房者…

出现丢包问题的情况以及解决方法

为什么会出现丢包&#xff1f; 我们在网络上传输数据的时候&#xff0c;数据需要经过很多的路由器/交换机&#xff08;交通枢纽&#xff09;进行传输&#xff0c;而路由器/交换机的结构是很复杂的&#xff0c;传输的数据量也是不确定的&#xff0c;可能这一会传输的数据比较少&…

mysql 03.查询(重点)

先准备测试数据&#xff0c;代码如下&#xff1a; -- 创建数据库 DROP DATABASE IF EXISTS mydb; CREATE DATABASE mydb; USE mydb;-- 创建student表 CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT male );-- 向student表插入数据…

vscode用ssh远程连接linux

1、vscode是利用ssh远程连接linux的&#xff0c;所以首先确保vscode已经安装了这两个插件 2、点击左下角的连接 3、选择Connect to Host…… 5、按格式输入 ssh 主机名ip 比如我的&#xff1a;ssh mnt192.168.198.128 6、选择第一个打开配置文件&#xff0c;确保输入正确 7、…

el-table :span-method合并单元格

2023.8.17今天我学习了如何使用el-table进行单元格的合并&#xff0c;效果如下&#xff1a; 在开发的过程中&#xff0c;如果有多个重复的值&#xff0c;我们希望可以进行合并显示&#xff0c;这样就不会显得重复太多&#xff0c;el-table有自带的方法&#xff1a; Element - …

安装编译器

安装MinGW&#xff0c;下载地址&#xff1a; MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net 下载x86_64-win32-seh&#xff0c;下载完解压到相应的路径下。

Leetcode-每日一题【剑指 Offer 32 - I. 从上到下打印二叉树】

题目 从上到下打印出二叉树的每个节点&#xff0c;同一层的节点按照从左到右的顺序打印。 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回&#xff1a; [3,9,20,15,7] 提示&#xff1a; 节点总数 < 1000 解题思路 1.题目要求我们从…

创建SpringBoot项目报错 - Process finished with exit code 1

错误信息 [ERROR] The build could not read 1 project -> [Help 1] [ERROR] [ERROR] The project com.example:ruoyi-excel-demo:0.0.1-SNAPSHOT (D:\Java\work\ruoyiExcelDemo\pom.xml) has 1 error [ERROR] Non-resolvable parent POM for com.example:ruoyi-e…

爬虫逆向实战(十六)--某建筑市场平台

一、数据接口分析 主页地址&#xff1a;某建筑市场平台 1、抓包 通过抓包可以发现数据接口是list 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 通过查看“响应”模块可以发现&#xff0c;返回的响应是…

【共同缔造 情暖襄阳】 暑期关爱未成年人志愿服务活动合集(三)

结合2023年襄阳市民政局“共同缔造 情暖襄阳”社会工作服务项目&#xff0c;在襄阳市民政局、襄州区民政局支持下&#xff0c;襄州社工协会联合肖湾街道育红社区开展暑期“希望家园”志愿服务活动&#xff0c;关爱未成年人。 8月4日&#xff0c;为培育孩子们广泛的兴趣爱好和动…

【JVM】垃圾回收算法

目录 一、判断对象已“死” 1.1、引用计数算法 1.2、可达性分析算法 1.3、引用的概念 二、垃圾收集算法理论 2.1、分代收集理论 三、垃圾收集算法 3.1、标记--清除算法 3.2、标记--复制算法 3.3、标记--整理算法 一、判断对象已“死” 在堆里面存放着Java世界中几乎所…