云南网站建设产品介绍,可以制作网站的软件是什么,网络推广培训推荐,莆田企业自助建站系统网站:http://www.cppblog.com/pansunyou/archive/2013/08/05/137563.html gSOAP学习笔记 虽然SOAP被有些人说太老土#xff0c;但在银行里仍有大量系统在使用#xff0c;前段时间在工作中接触到#xff0c;故记录一下。 gSOAP学习笔记 潘孙友 2010-12-27 于遵义 目录
一、基… 网站:http://www.cppblog.com/pansunyou/archive/2013/08/05/137563.html gSOAP学习笔记 虽然SOAP被有些人说太老土但在银行里仍有大量系统在使用前段时间在工作中接触到故记录一下。 gSOAP学习笔记 潘孙友 2010-12-27 于遵义 目录
一、基本概念1.1 关于SOAP1.2 关于gSOAP1.3 gSOAP编译器(命令行工具)1.3.1 wsdl2h1.3.2 socapcpp2
二、gSOAP开发Web Service服务端
三、gSOAP开发Web Service客户端
四、参考资料笔记中的代码一、基本概念 1.1 关于SOAP SOAP(Simple Object Access Protocol)即简单对象访问协议是在分布式的环境中交换数据的简单协议以XML作为数据传送语言。 SOAP有两种工作模式一种是RPC(Remote Procedure Call)另一种是Message-Oriented。MO可以利用XML来交换结构更复杂的数据。RPC模式的SOAP可以理解为这样一个开发协议SOAPRPCHTTPXML具有以下特点 采用HTTP作为通信协议采用客户/服务模式RPC作为统一的远程方法调用途径传送的数据使用XML格式。 看一个简单的请求及回复SOAP数据(真实数据) POST /wpsoap/ HTTP/1.1
Host: 127.0.0.1:10240
User-Agent: gSOAP/2.7
Content-Type: text/xml; charsetutf-8; action
Content-Length: 480
Connection: close
SOAPAction: ?xml version1.0 encodingUTF-8?
SOAP-ENV:Envelope xmlns:SOAP-ENVhttp://schemas.xmlsoap.org/soap/envelope/ xmlns:SOAP-ENChttp://schemas.xmlsoap.org/soap/encoding/ xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:xsdhttp://www.w3.org/2001/XMLSchema xmlns:ns1http://www.example.org/wpsoap/ xmlns:ns2urn:nszfptSOAP-ENV:Bodyns2:loginrequsernameadmin/usernamepassword3.14159/password/req/ns2:login/SOAP-ENV:Body/SOAP-ENV:EnvelopeHTTP/1.1 200 OK
Server: gSOAP/2.7
Content-Type: text/xml; charsetutf-8; action
Content-Length: 555
Connection: close?xml version1.0 encodingUTF-8?
SOAP-ENV:Envelope xmlns:SOAP-ENVhttp://schemas.xmlsoap.org/soap/envelope/ xmlns:SOAP-ENChttp://schemas.xmlsoap.org/soap/encoding/ xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:xsdhttp://www.w3.org/2001/XMLSchema xmlns:wpsoapurn:nszfptSOAP-ENV:Body SOAP-ENV:encodingStylehttp://schemas.xmlsoap.org/soap/encoding/wpsoap:tagRspLoginrspretCode0/retCoderetMessagelogin ok!/retMessage/rspsession01234567890/session/wpsoap:tagRspLogin/SOAP-ENV:Body/SOAP-ENV:Envelope这东西非常的复杂我仅仅记录一下使用到的部分。 1.2 关于gSOAP 引用http://blog.csdn.net/darkone/archive/2006/12/14/1442525.aspxgSOAP编译工具提供了一个SOAP/XML 关于C/C 语言的实现从而让C/C语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的Cweb服务工具包提供一组API函数类库来处理特定的SOAP数据结构这样就使得用户必须改变程序结构来适应相关的类库。与之相反gSOAP利用编译器技术提供了一组透明化的SOAP API并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。gSOAP的编译器能够自动的将用户定义的本地化的C或C数据类型转变为符合XML语法的数据结构反之亦然。这样只用一组简单的API就将用户从SOAP细节实现工作中解脱了出来可以专注与应用程序逻辑的实现工作了。gSOAP编译器可以集成C/C和Fortran代码通过一个Fortran到C的接口嵌入式系统其他SOAP程序提供的实时软件的资源和信息可以跨越多个操作系统语言环境以及在防火墙后的不同组织。gSOAP使编写web服务的工作最小化了。gSOAP编译器生成SOAP的代码来序列化或反序列化C/C的数据结构。gSOAP包含一个WSDL生成器用它来为你的web服务生成web服务的解释。gSOAP的解释器及导入器可以使用户不需要分析web服务的细节就可以实现一个客户端或服务端程序。照我理解gSOAP可以为我们生成soap服务器端客户端代码的框架我们只需实现具体的接口函数即可。而生成代码的工具就是上面文中提到的“gSOAP编译器”。 1.3 gSOAP编译器(命令行工具) 1.3.1 wsdl2h 此工具用来从WSDL文件生成c/c头文件。 wsdl2h -o 头文件名 WSDL文件名或URL
常用的其它参数
-o 文件名指定输出头文件
-n 名空间前缀 代替默认的ns
-c 产生纯C代码否则是C代码
-s 不要使用STL代码
-t 文件名指定type map文件默认为typemap.dat
-e 禁止为enum成员加上名空间前缀1.3.2 socapcpp2 此工具用来从头文件生成SOAP服务器及客户端代码还包括WSDL、测试用XML数据。 soapcpp2 头文件
常用选项
-C 仅生成客户端代码
-S 仅生成服务器端代码
-L 不要产生soapClientLib.c和soapServerLib.c文件
-c 产生纯C代码否则是C代码(与头文件有关)
-I 指定import路径见上文
-x 不要产生XML示例文件
-i 生成C包装客户端为xxxxProxy.h(.cpp)服务器端为xxxxService.h(.cpp)。二、gSOAP开发Web Service服务端 开发服务器程序需使用gSOAP生成服务器端代码框架。我们有两种做法 编写WSDL使用wsdl2h生成头文件再soapcpp2生成框架代码编写头文件使用soapcpp2生成框架代码 这两种方式结果是一样的最终都有产生头文件并生成代码。不同在于在项目的开发中需要维护的文件不同前者是需要维护WSDL文件后者维护头文件。 我个人觉得第二种方式更好用不仅仅是少了个步骤而是WSDL的语法太难写了有点XSD的味道。而头文件的编写更接近于程序员的思考方式比如定义消息结构定义接口名称等。 gSOAP是非常智能的它利用C/C的注释来获取信息所以在手工编写的头文件中注释是用用处的常以// gsoap 名字空间 …开头。做为学习我准备为php blog程序wordpress写一个web service接口名字叫wpsoap。 我开始写头文件(wpSoap.h)了出于学习目的我仅实现了两个接口一是用户登陆一是日志发布。 /*** file wpsoap.h* brief 为wordpress2.7提供web service接口** //gsoap开头行请勿删除.* * 1. 通过此文件生成WSDL 及 服务端代码* * mkdir -p srvSrcFromH* cd srvSrcFromH* soapcpp2 -L -S wpsoap.h -I /path/to/gsoap-2.8/gsoap/import/* * 2. 通过WSDL生成客户端代码* * mkdir -p clientSrcFromWSDL* cd clientSrcFromWSDL* wsdl2h.exe -o wpsoap.h ../srvSrcFromH/wpsoap.wsdl -I /path/to/gsoap-2.8/gsoap/import/* soapcpp2 -L -C wpsoap.h -I /path/to/gsoap-2.8/gsoap/import/** author pansunyougmail.com* version 1.0* date 2010-12-27
*///gsoap wpsoap service name: wpsoap
//gsoap wpsoap service namespace: http://www.example.org/wpsoap/
//gsoap wpsoap service location: http://192.168.0.187:10240/wpsoap/
//gsoap wpsoap service encoding: encoded
//gsoap wpsoap schema namespace: urn:nszfpt#import stlvector.h//通用回复
class wpsoap__tagCommResponse
{int retCode ; //回复码std::string retMessage ; //回复消息
};//[请求]用户登陆
class wpsoap__tagReqLogin
{std::string username ; //用户名std::string password ; //密码名文
};//[答复]用户登陆
class wpsoap__tagRspLogin
{wpsoap__tagCommResponse rsp ; //通用回复std::string session ; //会话标识
};//[接口]登陆接口
int wpsoap__login(wpsoap__tagReqLogin req, wpsoap__tagRspLogin rsp);//[请求]发布日志
class wpsoap__tagReqPost
{std::string title ; //标题std::string body ; //正文
};//[答复]发布日志
class wpsoap__tagRspPost
{wpsoap__tagCommResponse rsp ; //通用回复
};//[接口]发布日志接口
int wpsoap__post(wpsoap__tagReqPost req, wpsoap__tagRspPost rsp);在接口中我使用到了自定义的消息结构wp_soap_tag*这里的wpsoap__前缀是必须的这样soapcpp2才能为我们生成正确的代码。 之后我使用soapcpp2生成服务端代码框架: echo off
set path%cd%\..\..\contrib\gsoap-2.8\gsoap\bin\win32\;%path%mkdir srvSrcFromH 2nul
cd srvSrcFromH
soapcpp2.exe -L -S ..\res\wpSoap.h -I ..\..\..\contrib\gsoap-2.8\gsoap\import\
pause要编译出服务程序有这些代码还不够还需要自己写两个文件一个用来写main函数一个用来写wpsoap的接口函数当然可以放在一个文件里。最终我的服务器程序有以下文件另外还需要gsoap目录下的stdsoap2.cpp因为我把它编译为静态库了所以这里没列出来。 D:\wpSoapServer
| makeSrc.bat
| wpsoapimpl.cpp //这里实现了soapStub.h给出的接口
| wpsoapsrv.cpp //这里是main函数开始的地方
---res
| wpSoap.h
\---srvSrcFromHsoapC.cppsoapH.hsoapServer.cppsoapStub.hsoapwpsoapObject.hwpsoap.login.req.xmlwpsoap.login.res.xmlwpsoap.nsmapwpsoap.post.req.xmlwpsoap.post.res.xmlwpsoap.wsdlwpsoap.xsd每次我修改了res/wpSoap.h后我就运行一下makeSrc.bat自动重新生成srvSrcFromH目录里的所有东西并且这个目录里的所有代码是不需要手工维护的除非有特殊需要。 在服务器代码中我仅实现了以下两个函数(wpsoapimpl.cpp) int wpsoap__login(struct soap*, wpsoap__tagReqLogin req, wpsoap__tagRspLogin rsp);
int wpsoap__post(struct soap*, wpsoap__tagReqPost req, wpsoap__tagRspPost rsp);wpsoapsrv.cpp里的代码仅仅是调用gSOAP产生的代码来建立socket服务器基本不需维护。gSOAP是线程安全的可以将请求分配到线程池内实现高效服务但我仅为了走通gSOAP的使用流程没有这样使用。 具体做法可以参考http://www.cs.fsu.edu/~engelen/soapdoc2.html 三、gSOAP开发Web Service客户端 客户端代码本来也是可以通过为服务端编写的头文件生成的但是为了真实一点假设我无法获取服务器开发时使用的头文件仅仅有个公开的WSDL文件就是上面产生的srvSrcFromH /wpsoap.wsdl。 我用这个脚本来生成客户端框架代码 echo off
set path%cd%\..\..\contrib\gsoap-2.8\gsoap\bin\win32\;%path%mkdir clientSrcFromWSDL 2nul
cd clientSrcFromWSDL
wsdl2h.exe -o wpsoap.h ..\..\wpSoapServer\srvSrcFromH\wpsoap.wsdl
soapcpp2.exe -L -C wpsoap.h -I ..\..\..\contrib\gsoap-2.8\gsoap\import\
pause加上我测试用的代码wpsoapclient.cpp以及gosap目录里的stdsoap2.cpp我有了如下文件 D:\wpSoapClient
| makeSrc.bat
| wpsoapclient.cpp
\---clientSrcFromWSDLsoapC.cppsoapClient.cppsoapH.hsoapStub.hsoapwpsoapProxy.hwpsoap.hwpsoap.login.req.xmlwpsoap.login.res.xmlwpsoap.nsmapwpsoap.post.req.xmlwpsoap.post.res.xml客户端代码非常少仅仅是实现容错之类的都未考虑 /*** file wpsoapclient.cpp* brief 访问wpsoap服务** 调用wpsoap的客户端示例代码** author pansunyougmail.com* version 1.0* date 2010-12-27
*/#define _CRT_SECURE_NO_WARNINGS
#include cstdio
#include cstdlib
#include string
#include clientSrcFromWSDL/soapStub.h
#include clientSrcFromWSDL/soapwpsoapProxy.h
#include clientSrcFromWSDL/wpsoap.nsmapusing namespace std;int main(int argc, char*argv[])
{wpsoap wpsoapClient;if (argc2)wpsoapClient.endpoint argv[1];//1. 登陆string username admin;string password 3.14159;int r 0;ns2__tagReqLogin req;req.username username;req.password password;_ns2__login ns2__login;ns2__login.req req;_ns2__tagRspLogin rsp;r wpsoapClient.__ns1__login(ns2__login, rsp);if (r!0){fprintf(stderr, 调用soap接口失败!\n);return -1;}if (0!rsp.rsp-retCode){printf(登陆失败 retCode%d, retMessage%s\n,rsp.rsp-retCode, rsp.rsp-retMessage.c_str());return -1;}printf(登陆成功! [session%s]\n,rsp.session.c_str());ns2__tagReqPost reqPost;reqPost.body post article by wpsoap!;reqPost.title hello, wpsoap!;_ns2__post ns2__post;ns2__post.req reqPost;_ns2__tagRspPost ns2__tagRspPost;r wpsoapClient.__ns1__post(ns2__post, ns2__tagRspPost);if (r!0){fprintf(stderr, 调用soap接口失败!\n);return -1;}if (0!rsp.rsp-retCode){printf(发布日志失败 retCode%d, retMessage%s\n,rsp.rsp-retCode, rsp.rsp-retMessage.c_str());return -1;}printf(日志发布成功! [retMessage%s]\n, rsp.rsp-retMessage.c_str());return 0;
}四、参考资料 http://gsoap2.sourceforge.net/ http://www.cppprog.com/2009/0723/138.html http://hi.baidu.com/winnyang/blog/item/d5fd4f3df38f35cd9e3d625b.html http://www.cs.fsu.edu/~engelen/soap.html http://tangentsoft.net/mysql/