C++ 调用 SOAP Web Service

背景

首先,gSoap 肯定是个不错的选择,但是如果你的程序要调用多个 Web Services(即有多个 WSDL),gSoap 会比较麻烦。还有一个问题就是,gSoap 从 WSDL 自动生成的代码实在是太难用了。当然,这些都不是什么问题,真在的问题是许可证(License),gSoap 用在商业产品中是要收费的。

公司比较穷,舍不得花钱买 gSoap,但是 C++ 调 Web Service 还真没什么好办法。尝试了五六个半死不活的库后,最终锁定了 WWSAPI(Windows Web Services API)。

WWSAPI 的官方文档经常让人摸不着头脑,没有完整的示例,给出一段代码,常常需要几经调整才能使用。WWSAPI 自动生成的代码,是纯 C 的接口,在难用程度上,较 gSoap 有过之而无不及。在消息参数上,它强制使用双字节 Unicode,我们的输入输出都是 UTF8 的 std::string,于是莫名地多出很多编码转换。WWSAPI 需要你手动分配堆(heap),需要你指定消息的缓冲大小,而最严重的问题是,它不够稳定,特别是在子线程里调用时,莫名其妙连接就会断掉。

于是,我就动手自己写了个 webcc。
一开始 webcc 只支持 SOAP,名字就叫 csoap,后来支持了 REST,于是改名为 webcc,取 Web C++ 的意思。

原理

Webcc 没有提供从 WSDL 自动生成代码的功能,一来是因为这一过程太复杂了,二来是自动生成的代码一般都不好用。所以 webcc 最好搭配 SoapUI 一起使用。SoapUI 可以帮助我们为每一个 Web Service 操作(operation)生成请求的样例,基于请求样例,就很容易发起调用了,也避免了直接阅读 WSDL。

下面以 ParaSoft 提供的 Calculator 为例,首先下载 WSDL,然后在 SoapUI 里创建一个 SOAP 项目,记得勾上 "Create sample requests for all operations?" 这个选项,然后就能看到下面这样的请求样例了:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
<soapenv:Header/>
<soapenv:Body><cal:add><cal:x>1</cal:x><cal:y>2</cal:y></cal:add>
</soapenv:Body>
</soapenv:Envelope>

这个操作是 add,有两个参数:xy。此外值得注意的还有 XML namespace,比如 xmlns:cal="http://www.parasoft.com/wsdl/calculator/"

要调用这个 add 操作,只要发一个 HTTP 请求,并把上面这个 SOAP Envelope 作为请求的 Content。在 SoapUI 里把 Request 切换到 “Raw" 模式,就可以看到下面这样完整的 HTTP 请求:

POST http://ws1.parasoft.com/glue/calculator HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "add"
Content-Length: 300
Host: ws1.parasoft.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/"><soapenv:Header/><soapenv:Body><cal:add><cal:x>1</cal:x><cal:y>1</cal:y></cal:add></soapenv:Body>
</soapenv:Envelope>

所以 webcc 所做的,只不过是跟 ws1.parasoft.com 建立 TCP Socket 连接,然后发送上面这段内容而已。

用法

首先,创建一个类 CalcClient,继承自 webcc::SoapClient

#include <string>
#include "webcc/soap_client.h"class CalcClient : public webcc::SoapClient {
public:CalcClient() {Init();}

Init() 函数里,初始化 URL、host、port 等等:

private:void Init() {url_ = "/glue/calculator";host_ = "ws1.parasoft.com";port_ = "";  // Default to "80".service_ns_ = { "cal", "http://www.parasoft.com/wsdl/calculator/" };result_name_ = "Result";}

由于四个计算器操作(add, subtract, multiplydivide)都一致的具有两个参数,我们可以稍微封装一下,弄一个辅助函数叫 Calc

bool Calc(const std::string& operation,const std::string& x_name,const std::string& y_name,double x,double y,double* result) {// Prepare parameters.std::vector<webcc::Parameter> parameters{{ x_name, x },{ y_name, y }};// Make the call.std::string result_str;webcc::Error error = Call(operation, std::move(parameters), &result_str);// Error handling if any.if (error != webcc::kNoError) {std::cerr << "Error: " << error;std::cerr << ", " << webcc::GetErrorMessage(error) << std::endl;return false;}// Convert the result from string to double.try {*result = boost::lexical_cast<double>(result_str);} catch (boost::bad_lexical_cast&) {return false;}return true;
}

值得注意的是,作为局部变量的参数(parameters),利用了 C++11 的 Move 语义,避免了额外的拷贝开销。
当参数为很长的字符串时(比如 XML string),这一点特别有用。

最后,四个操作就是简单的转调 Calc 而已:

bool Add(double x, double y, double* result) {return Calc("add", "x", "y", x, y, result);
}bool Subtract(double x, double y, double* result) {return Calc("subtract", "x", "y", x, y, result);
}bool Multiply(double x, double y, double* result) {return Calc("multiply", "x", "y", x, y, result);
}bool Divide(double x, double y, double* result) {return Calc("divide", "numerator", "denominator", x, y, result);
}

局限

当然,webcc 有很多局限,比如:

  • 只支持 int, double, boolstring 这几种参数类型;
  • 只支持 UTF-8 编码的消息内容;
  • 一次调用一个连接;
  • 连接是同步(阻塞)模式,可以指定 timeout(缺省为 15s)。

依赖

在实现上,webcc 有下面这些依赖:

  • Boost 1.66+;
  • XML 解析和构造基于 pugixml;
  • 构建系统是 CMake,应该可以很方便地集成到其他 C++ 项目中。

C++ 调用 SOAP Web Service相关推荐

  1. Java如何通过WSDL文件来调用这些web service

    下面我们来看Java如何通过WSDL文件来调用这些web service: 注意,以下的代码并没有经过真正的测试,只是说明这些情况,不同版本的Axis相差很大,大家最好以apache网站上的例子为准, ...

  2. abap 调用外部web service 使用小结

    abap调用外部 web service 时,大致分为以下三个步骤 1,se80,选择package,点击创建enterprise service/web service-proxy client 2 ...

  3. 使用 Ajax 调用 SOAP Web 服务,第 1 部分: 构建 Web 服务客户机

    James Snell (jasnell@us.ibm.com), 软件工程师,新兴技术, IBM James Snell 是 IBM 的 software group 中的 emerging Int ...

  4. CORBA 简单了解和JAVA与C++互操以及C++调用Java web service

    CORBA了解 CORBA(Common Object Request Broker Architecture, 公共对象请求代理体系结构)是由OMG(对象管理组织,Object Management ...

  5. 调用天气预报Web Service

    调用天气Web Service             i.创建项目                 项目名称:weatherclient             ii.创建本地的wsdl文件    ...

  6. SOAP/Web Service/WSDL关系

    转载----------------------------------------------- 最近看了xml schema,xpah,和xslt的相关内容,感觉wsdl就是一个soap的sche ...

  7. SAP调用外部web service

    前提:外部提供可用的web service,通常为链接 1. SE80,创建web service proxy    1)SE80,选择package,右击->create->Enterp ...

  8. 【REST SOAP】REST和SOAP Web Service的区别比较

    今天遇到一个webservice协议的接口需求,在使用soupUI测试接口连通性的时候,发现使用soupUI新建一个SOAP项目的时候,WSDL链接总是报错打不开(厂家提供的接口规范上写的是SOAP协 ...

  9. Soap Web Service和Rest

    Soap: 是一个严格定义的信息交换协议,用于在Web Service中把远程调用和返回封装成机器可读的格式化数据.事实上SOAP数据使用XML数据格式,定义了一整套复杂的标签,以描述调用的远程过程, ...

最新文章

  1. 基于半监督学习的单体型组装算法
  2. Oauth2认证以及新浪微博开放平台应用
  3. Exchange2007中创建收件人对象、通讯组和地址列表和客户端访问
  4. java知识点--基础篇(5)
  5. Fallout 3完结
  6. python判断值是否为空(亲测)
  7. HDU - 2896 病毒侵袭(AC自动机)
  8. 异步重试_异步重试模式
  9. java溢出怎么处理_java数据溢出怎么处理?
  10. java策略模式学习
  11. 英特尔生产17个量子位超导芯片,现已交付合作伙伴
  12. 分表分库解决方案(mycat,tidb,shardingjdbc)
  13. CloudStack升级中文指南:4.1.x/4.2.x 至4.3版本
  14. 高等数学18讲(19版)7.29
  15. Vue3,Vite3,TS,Naive-UI整合TailwindCSS
  16. python 前缀和总结
  17. Thinkpad E430 移除网卡白名单
  18. 笔记本损耗60 计算机提示,笔记本电池损耗60%多怎么处理!
  19. 5、html标签中的两种关系
  20. 【悟空云课堂】第三十九期:违反信任边界(CWE-501: Trust Boundary Violation)

热门文章

  1. php arsort函数,php-常用函数
  2. IntelliJ IDEA License Activation系列验证爆错: This license BIG3CLIK6F has been cancelled d 解决
  3. 画布上面重叠事件_python学习手札turtle库的键盘事件
  4. HTML表单效果图,html-图片/表格/表单
  5. python opencv识别点个数_python+OpenCV 特征点检测
  6. 比较有名的CSS,优雅地写css
  7. kafka jar包_Windows环境下Flink消费Kafka实现热词统计
  8. 网警已进入本群代码_“闯黄灯”记3分罚200元?沈阳网警这样回应
  9. vue项目 构建 打包 发布 三部曲
  10. 计算机组成原理试卷分析,《计算机组成原理与汇编语言》试卷分析报告.doc.docx...