gsoap工具下载地址:
https://sourceforge.net/projects/gsoap2/files/
wsdl example地址:
http://schemas.xmlsoap.org/wsdl/soap12/soap12wsdl.htm
soap参考网址:
http://www.cs.fsu.edu/~engelen/soap.html
https://www.genivia.com/dev.html
https://www.genivia.com/examples/calc/index.html
soap 用户手册:
https://www.genivia.com/doc/soapdoc2.pdf
MarkdownPad2下载:
MarkdownPad2破解:
Email address :
Soar360@live.com
License key:
GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M5SN6bnxn2kSE8qHqNY5QaaRxmO3YSMHxlv2EYpjdwLcPwfeTG7kUdnhKE0vVy4RidP6Y2wZ0q74f47fzsZo45JE2hfQBFi2O9Jldjp1mW8HUpTtLA2a5/sQytXJUQl/QKO0jUQY4pa5CCx20sV1ClOTZtAGngSOJtIOFXK599sBr5aIEFyH0K7H4BoNMiiDMnxt1rD8Vb/ikJdhGMMQr0R4B+L3nWU97eaVPTRKfWGDE8/eAgKzpGwrQQoDh+nzX1xoVQ8NAuH+s4UcSeQ==
wsdl2h.exe
该工具是可以根据输入的wsdl或XSD或URL,产生相应的C/C++形式的.h(不能直接引用),供soapcpp2使用。
Option | Description |
-a | generate indexed struct names for local elements with anonymous types |
-b | bi-directional operations to serve one-way response messages (duplex) |
-c | generate C source code |
-c++ | generate C++ source code |
-c++11 | generate C++11 source code |
-d | use DOM to populate xs:any and xsd:anyType elements |
-D | make attribute members with default values optional with pointers |
-e | don’t qualify enum names This option is for backward compatibility with gSOAP 2.4.1 and earlier. The option does not produce code that conforms to WS-I Basic Profile 1.0a. |
-f | generate flat C++ class hierarchy for schema extensions |
-g | generate global top-level element declarations |
-h | print help information |
-I path | use path to locate source files for #import |
-i | don’t import (advanced option) |
-j | don’t generate SOAP ENV Header and SOAP ENV Detail definitions |
-k | don’t generate SOAP ENV Header mustUnderstand qualifiers |
-l | include license information in output |
-m | use xsd.h module to import primitive types |
-N name | use name for service prefixes to produce a service for each binding |
-n name | use name as the base namespace prefix name instead of ns |
-O1 | optimize by omitting duplicate choice/sequence members |
-O2 | optimize -O1 and omit unused schema types (unreachable from roots) |
-o file | output to file |
-P | don’t create polymorphic types inherited from xsd anyType |
-p | create polymorphic types inherited from base xsd anyType This is automatically performed when WSDL contains polymorphic definitions |
-q name | use name for the C++ namespace of all declarations |
-R | generate REST operations for REST bindings in the WSDL |
-r host[:port[:uid:pwd]] | connect via proxy host, port, and proxy credentials |
-r:uid:pwd | connect with authentication credentials (digest auth requires SSL) |
-s | don’t generate STL code (no std::string and no std::vector) |
-t file | use type map file instead of the default file typemap.dat |
-U | map Unicode XML names to UTF8-encoded Unicode C/C++ identifiers |
-u | don’t generate unions |
-V | display the current version and exit |
-v | verbose output |
-W | suppress warnings |
-w | always wrap response parameters in a response struct |
-x | don’t generate XML any/anyAttribute extensibility elements |
-y | generate typedef synonyms for structs and enums |
-z1 | compatibility with 2.7.6e: generate pointer-based arrays |
-z2 | compatibility with 2.7.15: qualify element/attribute referenced members |
-z3 | compatibility with 2.7.16 to 2.8.7: qualify element/attribute references |
-z4 | compatibility up to 2.8.11: don’t generate union structs in std::vector |
-z5 | compatibility up to 2.8.15: don’t include minor improvements |
-z6 | compatibility up to 2.8.17: don’t include minor improvements |
-z7 | compatibility up to 2.8.59: don’t generate std::vector of class of union |
- | don’t generate USCORE (replace with Unicode x005f) |
soapcpp2.exe
Soapcpp2是一个根据.h文件生成若干支持webservice的代码生成工具,生成的代码文件包括webservice客户端和服务器的实现框架,XML数据绑定等,具体说明如下:
Option | Description |
-1 | generate SOAP 1.1 bindings |
-2 | generate SOAP 1.2 bindings |
-0 | no SOAP bindings, use REST |
-C | generate client-side code only |
-S | generate server-side code only |
-T | generate server auto-test code |
-Ec | generate extra routines for deep data copying |
-Ed | generate extra routines for deep data deletion |
-Et | generate extra routines for data traversals with walker functions |
-L | do not generate soapClientLib/soapServerLib |
-a | use SOAPAction with WS-Addressing to invoke server-side operations |
-A | require SOAPAction to invoke server-side operations |
-b | serialize byte arrays char[N] as string |
-c | generate pure C code |
-d <path> | save sources in directory specified by <path> |
-e | generate SOAP RPC encoding style bindings |
-f N | multiple soapC files, with N serializer definitions per file (N ≥ 10) |
-h | print a brief usage message |
-i | generate service proxies and objects inherited from soap struct |
-j | generate C++ service proxies and objects that can share a soap struct |
-I <path> | use <path> for #import (paths separated with ’:’ or ’;’ for windows) |
-l | generate linkable modules (experimental) |
-m | generate Matlabtm code for MEX compiler |
-n | when used with -p, enables multi-client and multi-server builds: sets compiler option WITH NONAMESPACES, see Section 9.11 saves the namespace mapping table with name <name> namespaces instead of namespaces renames soap serve() into <name> serve() and soap destroy() into <name> destroy() |
-p <name> | save sources with file name prefix <name> instead of “soap” |
-q <name> | use name for the C++ namespace of all declarations |
-r | generate soapReadme.md report |
-s | generates deserialization code with strict XML validation checks |
-t | generates code to send typed messages (with the xsi:type attribute) |
-u | uncomment comments in WSDL/schema output by suppressing XML comments |
-V | display the current version and exit |
-v | verbose output |
-w | do not generate WSDL and schema files |
-x | do not generate sample XML message files |
-y | include C/C++ type access information in sample XML messages |
-z1 | compatibility: generate old-style C++ service proxies and objects |
-z2 | compatibility with 2.7.x: omit XML output for NULL pointers |
-z3 | compatibility with <= 2.8.30: _param_N indexing; nillable pointers |
生成文件的描述
File Name | Description |
soapStub.h | A modified and annotated header file produced from the input header file |
soapH.h | Main header file to be included by all client and service sources |
soapC.cpp | Serializers and deserializers for the specified data structures |
soapClient.cpp | Client stub routines for remote operations |
soapServer.cpp | Service skeleton routines |
soapClientLib.cpp | Client stubs combined with local static (de)serializers |
soapServerLib.cpp | Service skeletons combined with local static (de)serializers |
soapXYZProxy.h | A C++ proxy object (link with soapC.cpp soapClient.cpp) |
soapXYZProxy.h | With option -i: proxy object (link with soapC.cpp and soapXYZProxy.cpp) |
soapXYZProxy.cpp | With option -i: proxy code |
soapXYZObject.h | A C++ server object (link with soapC.cpp and soapServer.cpp) |
soapXYZService.h | With option -i: server object (link with soapC.cpp and soapXYZService.cpp) |
soapXYZService.cpp | With option -i: server code |
.xsd | An ns.xsd file is generated with an XML Schema for each namespace prefix ns used by a data structure in the header file input to the compiler, see Section 7.2.9 |
.wsdl | A ns.wsdl file is generated with an WSDL description for each namespace prefix ns used by a service operation in the header file input to the compiler, see Section 7.2.9 |
.xml | Several SOAP/XML request and response files are generated. These are example message files are valid provided that sufficient schema namespace directives are added to the header file or the generated .nsmap namespace table for the client/service is not modified by hand |
.nsmap | A ns.nsmap file is generated for each namespace prefix ns used by a service operation in the header file input to the compiler, see Section 7.2.9. The file contains a namespace mapping table that can be used in the client/service sources |
File Name | Description |
stdsoap2.h | Header file of stdsoap2.cpp runtime library |
stdsoap2.c | Runtime C library with XML parser and run-time support routines |
stdsoap2.cpp | Runtime C++ library identical to stdsoap2.c |
calc.wsdl
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
targetNamespace="http://WebCalculator/test/"
xmlns:tns="http://WebCalculator/test/"
xmlns:tnst="http://CalculatorType/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" >
<wsdl:types>
<xsd:schema
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://CalculatorType/">
<xsd:element name="addRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" type="xsd:int"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="addResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="minusRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" type="xsd:int"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="minusResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="multiRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" type="xsd:int"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="multiResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="divRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" type="xsd:int"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="divResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="addRequestMsg">
<wsdl:part name="parameters" element="tnst:addRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="addResponseMsg">
<wsdl:part name="parameters" element="tnst:addResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="minusRequestMsg">
<wsdl:part name="parameters" element="tnst:minusRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="minusResponseMsg">
<wsdl:part name="parameters" element="tnst:minusResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="multiRequestMsg">
<wsdl:part name="parameters" element="tnst:multiRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="multiResponseMsg">
<wsdl:part name="parameters" element="tnst:multiResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="divRequestMsg">
<wsdl:part name="parameters" element="tnst:divRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="divResponseMsg">
<wsdl:part name="parameters" element="tnst:divResponse">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="calcServicePortType">
<wsdl:operation name="add">
<wsdl:input name="addRequest" message="tns:addRequestMsg">
</wsdl:input>
<wsdl:output name="addResponse" message="tns:addResponseMsg">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="minus">
<wsdl:input name="minusRequest" message="tns:minusRequestMsg">
</wsdl:input>
<wsdl:output name="minusResponse" message="tns:minusResponseMsg">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="multi">
<wsdl:input name="multiRequest" message="tns:multiRequestMsg">
</wsdl:input>
<wsdl:output name="multiResponse" message="tns:multiResponseMsg">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="div">
<wsdl:input name="divRequest" message="tns:divRequestMsg">
</wsdl:input>
<wsdl:output name="divResponse" message="tns:divResponseMsg">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="calcServiceHttpBinding" type="tns:calcServicePortType">
<wsdlsoap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="add">
<wsdlsoap:operation/>
<wsdl:input name="addRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="minus">
<wsdlsoap:operation/>
<wsdl:input name="minusRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="minusResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="multi">
<wsdlsoap:operation/>
<wsdl:input name="multiRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="multiResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="div">
<wsdlsoap:operation/>
<wsdl:input name="divRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="divResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="calcService">
<wsdl:port name="calcServiceHttpPort" binding="tns:calcServiceHttpBinding">
<wsdlsoap:address location="http://localhost:8080/test/services/calservice"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
wsdl2h.exe -c
soapcpp2.exe -c -r -L calc.h
客户端代码:
#include <stdlib.h>
#include <string.h>
#include "../SoapSource/calcServiceHttpBinding.nsmap"
#include "../SoapSource/soapStub.h"
#include "../SoapSource/soapH.h"
/* the Web service endpoint URL */
const char server[] = "http://localhost:8080/";
struct requestData {
int in0;
int in1;
};
struct responseData {
int out;
};
int main(int argc, char ** argv)
{
printf("hello soap I'm soap client!\n");
struct requestData request;
struct responseData response;
if (argc < 4)
{
fprintf(stderr, "Usage: [add|sub|mul|div] num num\n");
exit(0);
}
request.in0 = atoi(argv[2]);
request.in1 = atoi(argv[3]);
struct soap *soap = soap_new1(SOAP_XML_INDENT); /* new context */
switch (*argv[1])
{
case 'a':
soap_call___ns1__add(soap, server, "add", (struct _ns2__addRequest *)&request, (struct _ns2__addResponse *)&response);
break;
case 's':
soap_call___ns1__minus(soap, server, "sub", (struct _ns2__minusRequest *)&request, (struct _ns2__minusResponse *)&response);
break;
case 'm':
soap_call___ns1__multi(soap, server, "mul", (struct _ns2__multiRequest *)&request, (struct _ns2__multiResponse *)&response);
break;
case 'd':
soap_call___ns1__div(soap, server, "div", (struct _ns2__divRequest *)&request, (struct _ns2__divResponse *)&response);
break;
default:
fprintf(stderr, "Unknown command\n");
exit(0);
}
if (soap->error)
soap_print_fault(soap, stderr);
else
printf("result = %d\n", response.out);
soap_destroy(soap); /* delete deserialized objects */
soap_end(soap); /* delete heap and temp data */
soap_free(soap); /* we're done with the context */
return 0;
}
服务端代码:
#include <stdlib.h>
#include <string.h>
#include "../SoapSource/calcServiceHttpBinding.nsmap"
#include "../SoapSource/soapStub.h"
#include "../SoapSource/soapH.h"
int port = 8080;
int main(int argc, char ** argv)
{
SOAP_SOCKET m; /* master socket */
struct soap *soap = soap_new(); /* new context */
printf("hello soap I'm soap server!\n");
soap->send_timeout = soap->recv_timeout = 5; /* 5 sec socket idle timeout */
soap->transfer_timeout = 30; /* 30 sec message transfer timeout */
m = soap_bind(soap, NULL, port, 100);
if (soap_valid_socket(m))
{
while (soap_valid_socket(soap_accept(soap)))
{
fprintf(stderr, "Socket connection successful.\n");
soap_serve(soap); /* serve request */
soap_destroy(soap); /* delete deserialized objects */
soap_end(soap); /* delete heap and temp data */
}
}
soap_print_fault(soap, stderr);
soap_destroy(soap); /* delete deserialized objects */
soap_end(soap); /* delete heap and temp data */
soap_free(soap); /* we're done with the context */
return 0;
}
/** Web service operation '__ns1__add' (returns SOAP_OK or error code) */
SOAP_FMAC5 int SOAP_FMAC6 __ns1__add(struct soap *soap, struct _ns2__addRequest *ns2__addRequest, struct _ns2__addResponse *ns2__addResponse)
{
ns2__addResponse->out = ns2__addRequest->in0 + ns2__addRequest->in1;
return SOAP_OK;
}
/** Web service operation '__ns1__minus' (returns SOAP_OK or error code) */
SOAP_FMAC5 int SOAP_FMAC6 __ns1__minus(struct soap *soap, struct _ns2__minusRequest *ns2__minusRequest, struct _ns2__minusResponse *ns2__minusResponse)
{
ns2__minusResponse->out = ns2__minusRequest->in0 - ns2__minusRequest->in1;
return SOAP_OK;
}
/** Web service operation '__ns1__multi' (returns SOAP_OK or error code) */
SOAP_FMAC5 int SOAP_FMAC6 __ns1__multi(struct soap *soap, struct _ns2__multiRequest *ns2__multiRequest, struct _ns2__multiResponse *ns2__multiResponse)
{
ns2__multiResponse->out = ns2__multiRequest->in0 * ns2__multiRequest->in1;
return SOAP_OK;
}
/** Web service operation '__ns1__div' (returns SOAP_OK or error code) */
SOAP_FMAC5 int SOAP_FMAC6 __ns1__div(struct soap *soap, struct _ns2__divRequest *ns2__divRequest, struct _ns2__divResponse *ns2__divResponse)
{
ns2__divResponse->out = ns2__divRequest->in0 / ns2__divRequest->in1;
return SOAP_OK;
}