在SOAP协议金蝶客户端协议调试中出现28错误SOAP_DIME_END 28 End of DIME error,这是什么原因,怎么解决这个问题

dime 是什么意思_百度知道
dime 是什么意思
美元中的一角硬币,1dime=10cents
采纳率:21%
为您推荐:
其他类似问题
dime的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。SOAP 错误代码表_图文_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
SOAP 错误代码表
&&SOAP 错误代码表
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢gSOAP 2.8.68 User Guide
gSOAP 2.8.68 User Guide
Robert van Engelen Genivia Inc
Jun 29, 2018
Copyright (C)
Robert A. van Engelen, Genivia Inc, All Rights Reserved.
&&Introduction
The gSOAP tools provide an automated SOAP and XML data binding for C and C++
based on compiler technologies.
The tools simplify the development
of SOAP/XML Web services and XML
application in C and C++ using autocode generation and advanced mapping
methods. Most toolkits for Web services adopt a WSDL/SOAP-centric view and
offer APIs that require the use of class libraries for XML-specific
data structures. This forces a user to adapt the application logic to
these libraries because users have to write code to populate XML and extract
data from XML using a vendor-specific API. This often leads to fragile
solutions with little or no assurances for data consistency, type safety, and
XML validation. By contrast, gSOAP provides a type-safe and transparent
solution through the use of compiler technology that hides irrelevant WSDL-,
SOAP-, REST-, and XML-specific protocol details from the user, while
automatically ensuring XML validity checking, memory management, and type-safe
serialization. The gSOAP tools automatically map native and user-defined C and
C++ data types to semantically equivalent XML data types and vice-versa.
result, full SOAP/REST XML interoperability is achieved with a simple API
relieving the user from the burden of WSDL/SOAP/XML details, thus enabling him
or her to concentrate on the application-essential logic.
The gSOAP tools support the integration of (legacy) C/C++
codes (and other programming languages when a C interface is available),
embedded systems, and real-time software in SOAP/XML
applications that share
computational resources and information with other SOAP applications, possibly
across different platforms, language environments, and disparate organizations
located behind firewalls.
The gSOAP tools are also popular to implement XML data binding in C and C++.
This means that application-native data structures can be encoded in XML
automatically, without the need to write conversion code. The tools also
produce XML schemas for the XML data binding, so external applications can
consume the XML data based on the schemas.
&&Getting Started
To start building Web services applications or automate XML data bindings with gSOAP, you need:
The gSOAP package from
and select the gSOAP toolkit commercial edition, or download the GPL open source version from SourceForge .
A C or C++ compiler.
You may want to install OpenSSL and the Zlib libraries to enable SSL (HTTPS) and compression. These libraries are available for most platforms and are often already installed.
The gSOAP software is self-contained, so there is no need to download any third-party
software, except when you want to use OpenSSL for HTTPS and/or Zlib compression.
The gSOAP distribution package includes:
The wsdl2h WSDL/schema converter and data binding tool.
The soapcpp2 stub/skeleton compiler and code generator.
Binaries of these two tools are included in the gSOAP package in
gsoap/bin for Windows and Mac OS plarforms, see also the README
files in the package for more details.
Although gSOAP tools are available in binary format for several platforms, the
code generated by these tools are all equivalent. This means that the generated
source codes can be transferred to other platforms and locally compiled.
If you don't have the binaries or if you want to rebuild them, you need
Bison (or Yacc) to build soapcpp2.
Flex (or Lex) to build soapcpp2.
A C++ compiler to build wsdl2h.
Bison and Flex are preferred. Both are released under open source licenses that
are compatible with gSOAP's licenses.
Bison is available from
Flex is available from
You can also build soapcpp2 without Bison and Flex installed, see
installation instructions on the gSOAP web site.
The gSOAP engine is built as a library libgsoap.a and
libgsoap++.a with separate versions of these two libgsoapssl.a and libgsoapssl++.a that support SSL. See the
README.txt instructions on how to build these libraries with the
platform-independent gSOAP package's autoconf and automake. Alternatively, you
can compile and link the engine's source code stdsoap2.c (or
stdsoap2.cpp for C++) directly with your code.
The gSOAP packages contain numerous examples in the samples directory.
Run make to build the example applications. The examples are also meant
to demonstrate different features of gSOAP.
A streaming MTOM attachment server and client application
demonstrate efficient file exchanges in samples/mtom-stream. An SSL-secure Web
server application demonstrates the generation of dynamic content for Web
browsing and Web services functionality at the same time, see
samples/webservice. And much more.
&&Quick Start: Developing a Web Service Client Application
The gSOAP tools minimize application adaptation efforts for building Web
Services by using a XML data binding for C and C++ implemented by
advanced XML schema analyzers and source-to-source code generation tools.
The gSOAP wsdl2h tool imports one or more
WSDLs and XML schemas and generates a gSOAP header file with familiar C/C++ syntax to define the Web service operations
and the C/C++ data types. The gSOAP soapcpp2
compiler then takes this
header file and generates XML serializers for the data types (soapH.h and
soapC.cpp), the client-side stubs (soapClient.cpp), and server-side
skeletons (soapServer.cpp).
The gSOAP soapcpp2 compiler can also generate WSDL definitions for
implementing a service from scratch, i.e.&without defining a WSDL first. This
"closes the loop" in that it enables Web services development from WSDL or
directly from a set op C/C++ operations in a header file without the need for
users to analyze Web service details.
You only need to follow a few steps to execute the tools from the command line
or Makefile (see also MSVC++ project examples in the samples directory
with tool integration in the MSVC++ IDE). For example, to generate code for the
calculator Web service, we run the wsdl2h tool from the
command line on the URL of the WSDL and use option -o to specify the
output file:
wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
This generates the calc.h service definition header file with service
operation definitions and types for the operation's data. This
header file is then to be processed with soapcpp2 to generate the stub and/or
skeleton code and XML serialization routines. The
calc.h file includes all documentation, so you can use Doxygen
() to automatically generate the documentation pages for
your development.
The wsdl2h-generated service definitions header file also contains information on the use of the service, such as WS-Policy assertions when applicable.
In this example we are developing a C++ API for the calculator service. By
default, gSOAP assumes you will use C++ with STL.
To build without STL, use option
wsdl2h -s -o calc.h http://www.genivia.com/calc.wsdl
To build a pure C application, use option -c:
wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
Important: Visual Studio users shopuld make sure to compile all gSOAP
source files in C++ compilation mode. If you migrate to a project file
.vcproj, please set CompileAs="2" in your .vcproj file.
We have not yet generated the stubs for the C/C++ API. To do so, run the soapcpp2 compiler:
soapcpp2 -i -C -Iimport calc.h
Option -i (and alternatively option -j) indicates that we want C++ proxy and server objects that
include the client (and server) code, -C indicates client-side only files
(soapcpp2 generates both client and server stubs and skeletons by
default). Option -I is needed to import the stlvector.h file from the import directory in the gSOAP package to support serialization of STL vectors.
Suppose we develop a C++ client for the calculator service using wsdl2h -o calc.h http://www.genivia.com/calc.wsdl and soapcpp2 -i -C calc.h.
We use the generated soapcalcProxy class and
calc.nsmap XML namespace mapping table to access the Web
service. The soapcalcProxy class is a proxy to invoke the
#include "soapcalcProxy.h"
#include "calc.nsmap"
int&main()
&&&double&
&&&if&(service.add(1.0, 2.0, result) == SOAP_OK)
&&&&&&std::cout && "The sum of 1.0 and 2.0 is " && result && std::
&&&&&&service.soap_stream_fault(std::cerr);
&&&service.destroy(); // delete data and release memory
To complete the build, compile the code above and compile and link this with the generated soapC.cpp,
soapcalcProxy.cpp, and the run-time gSOAP engine -lgsoap++ (or use source stdsoap2.cpp in case libgsoap++.a is not installed) with your code.
Suppose we develop a client in C using wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl and soapcpp2 -C calc.h. In this case our code uses a simple C function call to invoke the service and we also need to explicitly delete data and the context with soap_end and soap_free:
#include "soapH.h"
#include "calc.nsmap"
int&main()
&&&struct soap *soap = soap_new();
&&&if&(soap_call_ns__add(soap, 1.0, 2.0, &result) == SOAP_OK)
&&&&&&printf("The sum of 1.0 and 2.0 is %lg\n", result);
&&&&&&soap_print_fault(soap, stderr);
&&&soap_end(soap);
&&&soap_free(soap);
The calculator example is fairly simple and used here to illustrate the
development process. The development process for large-scale XML applications
is similar. More extensive examples can be found in the samples directory
in the gSOAP package.
&&Quick Start: Developing a Web Service
Developing a service application is easy too. We will use CGI here because it
is a simple mechanism. This is not the preferred deployment mechanism. Because
CGI is slow and stateless. Faster services can be developed as a stand-alone
gSOAP HTTP/HTTPS server (but see comments at the end of this section) or, as
preferred and recommended for security reasons, the use of Apache module or IIS with the mod_gsoap ISAPI extension (included in the gSOAP package under
gsoap/mod_gsoap with instructions).
Suppose we implement a CGI-based service that returns the time in GMT. The
Common Gateway Interface (CGI) is a simple mechanism to publish services on
your Web site.
For this example we start with a gSOAP header file, currentTime.h which contains the service definitions. Such a file can be obtained from a WSDL using wsdl2h when a WSDL is available. When a WSDL is not available, you can define the service in C/C++ definitions in a newly created header file and let the gSOAP tools generate the source code and WSDL for you.
Our currentTime service only has an output parameter, which is the
current time defined in our currentTime.h gSOAP service specification:
// File: currentTime.h
//gsoap ns service name: currentTime
//gsoap ns service namespace: urn:currentTime
//gsoap ns service location: http://www.yourdomain.com/currentTime.cgi
int&ns__currentTime(time_t& response);
Note that we associate an XML namespace prefix ns and namespace name urn:currentTime with the service WSDL and SOAP/XML messages. The gSOAP tools
use a special convention for identifier names that are part of a namespace: a
namespace prefix (ns in this case) followed by a double underscore
__. This convention is used to resolve namespaces and to avoid name
clashes. The ns namespace prefix is bound to the urn:currentTime
namespace name with the //gsoap directive. The //gsoap directives
are used to set the properties of the service, in this case the name,
namespace, and location endpoint.
The service implementation for CGI requires a soap_serve call on a soap context created with soap_new. The service operations are implemented as functions, which are called by the RPC dispatcher soap_serve:
// File: currentTime.cpp
#include "soapH.h" // include the generated declarations
#include "currentTime.nsmap" // include the XML namespace mappings
int&main()
&&&// create soap context and serve one CGI-based request:
&&&return&soap_serve(soap_new());
int&ns__currentTime(struct&soap *soap, time_t& response)
&&&response = time(0);
&&&return&SOAP_OK;
Note that we pass the soap struct with the gSOAP context information to the
service routine. This can come in handy to determine properties of the connection
and to dynamically allocate data with soap_malloc(soap, num_bytes) that
will be automatically deleted when the service is finished.
We run the soapcpp2 compiler on the header file to generate the
server-side code:
soapcpp2 -S currentTime.h
and then compile the CGI binary:
c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp stdsoap2.cpp
You will find stdsoap2.cpp in the gsoap dir. Or after installation
you can link with libgsoap++ instead of using the stdsoap2.cpp
c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp -lgsoap++
To activate the service, copy the currentTime.cgi binary to your
bin-cgi directory using the proper file permissions.
The soapcpp2 tool generated the WSDL definitions
currentTime.wsdl. You can use the WSDL to advertize your service.
You don't need to use this WSDL to develop a gSOAP client. You can use the
currentTime.h file with soapcpp2 option -C to generate
client-side code.
A convenient aspect of CGI is that it exchanges messages over standard
input/output. Therefore, you can run the CGI binary on the auto-generated
example request XML file to test your server:
./currentTime.cgi
currentTime.currentTime.req.xml
and this displays the server response in SOAP XML.
The above approach works also for C. Just use soapcpp2 option -c in
addition to the -S option to generate ANSI C code. Of course, in C we use
pointers instead of references and the currentTime.h file should be
adjusted to use C-only types.
A more elegant server implementation in C++ can be obtained by using the
soapcpp2 option -i (or -j) to generate C++ client-side proxy and
server-side service objects as classes that you can use to build clients and
services in C++. The option removes the generation of soapClient.cpp and
soapServer.cpp, since these are no longer needed when we have classes
that implement the client and server logic:
soapcpp2 -i -S currentTime.h
This generates soapcurrentTimeService.h and
soapcurrentTimeService.cpp files, as well as auxiliary files
soapStub.h (included by default by all codes) and currentTime.nsmap.
Using the currentTimeService object we rewrite the CGI server as:
// File: currentTime.cpp
#include "soapcurrentTimeService.h" // include the proxy declarations
#include "currentTime.nsmap" // include the XML namespace mappings
int&main()
&&&// create server and serve one CGI-based request:
&&&currentTimeS
&&&server.serve();
&&&server.destroy();
int&currentTimeService::currentTime(time_t& response)
&&&response = time(0);
&&&return&SOAP_OK;
Compile with
c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapcurrentTimeService.cpp -lgsoap++
and install the binary as CGI. To install the CGI binary please consult your
Web server documentation on how to deploy CGI applications.
To run the server as a stand-alone iterative (non-multithreaded) server on port
8080 until accept() timeout times out or an error occurs:
if&(server.run(8080))
&&&server.soap_stream_fault(std::cerr);
To run the server as a stand-alone iterative server on port 8080 while ignoring
common errors until a TCP error occurs:
while&(server.run(8080) != SOAP_OK)
&&&if(server.soap-&error == SOAP_TCP_ERROR)
&&&&&&break;
&&&server.soap_stream_fault(std::cerr);
To implement threaded services, please see Section&. These
stand-alone Web Services that handle multiple SOAP requests by spawning a
thread for each request. Thread pooling is also an option. The use of Apache
and IIS modules to deploy gSOAP services is preferred and recommended to ensure load balancing, access control, tracing, security, and so on.
For more information on server-side service classes, see
Section&. For more information on client-side proxy classes,
see Section&.
&&Quick Start: XML Data Bindings
Or in other words, how to map schemas (XSD files) to C/C++ bindings for
automatically reading and writing XML data.
The XML C/C++ data binding in gSOAP provides and automated mechanism to encode
any C and C++ data type in XML (and decode XML back to C/C++ data). An XML
schema (XSD file) can be transformed into a set of C or C++ definitions
that can be readily incorporated into your application to manipulate XML with
much more ease than DOM or SAX. Essentially, each XML component definition in
an XML schema has a C/C++ data type representation that has equivalent type
properties. The advantage of this approach is immediately apparent when we look
at an XSD complexType that maps to a class:
&complexType name="Address">
class&ns__Address
&&&&sequence>
&&&&&&&element name="name" type="string"/>
&&&&&&&element name="home" type="tns:Location" minOccurs="0"/>
&&&ns__Location *
&&&&&&&element name="phone" type="unsignedLong"/>
&&&ULONG64
&&&&&&&element name="dob" type="dateTime"/>
&&&&/sequence>
&&&&attribute name="ID" type="int" use="required"/>
&&&@int&ID;
&/complexType>
In this way, an automatic mapping
between XML elements of the XML schema and members of a class is created.
No DOM traversals and SAX events are needed.
In addition, the XML C/C++ data binding makes XML manipulation type safe. That
is, the type safety of C/C++ ensures that only valid XML documents can be
parsed and generated.
The wsdl2h tool performs the mapping of WSDL and XML schemas to C and/or C++ automatically. The output of wsdl2h is an annotated header file that includes comments and documentation on the use of the C/C++ declarations in a SOAP/XML client/server or in a generic application for reading and writing XML using the auto-generated serializers.
We will illustrate this further with an example. Suppose we have an XML document with a book record:
&book isbn="">
&&&&title>Farewell John Doe&/title>
&&&&publisher>ABC's is our Name&/publisher>
&/book>
An example XML schema that defines the book element and type could be
&schema ...>
&&&&element name="book">
&&&&&&&complexType>
&&&&&&&&&&sequence>
&&&&&&&&&&&&&element name="title" type="string" minOccurs="1"/>
&&&&&&&&&&&&&element name="publisher" type="string" minOccurs="1"/>
&&&&&&&&&&/sequence>
&&&&&&&&&&attribute name="isbn" type="unsignedLong" use="required"/>
&&&&&&&/complexType>
&&&&/element>
&/schema>
Using wsdl2h we translate the XML schema that defines the book type and root element to a class definition:
class book
&&&@ULONG64
Note that annotations such as @ are used to distinguish attributes
from elements. These annotations are gSOAP-specific and are handled by the soapcpp2 tool to generate serializers for the data type(s) for reading and writing XML.
The soapcpp2 tool generates all
the necessary code to parse and generate XML for book objects. Validation
constraints such as minOccurs="1" and use="required" are included
in the generated code as checks.
To write the XML representation of a book, we first create a soap engine context and use it with soap_write_book (generated by soapcpp2) to write the object in XML to standard output:
soap *ctx = soap_new1(SOAP_XML_INDENT); // new context with option
bk.isbn = ;
bk.title = "Farewell John Doe";
bk.publisher = "ABC's is our Name";
if&(soap_write_book(ctx, &bk) != SOAP_OK)
&&&... error ...
soap_destroy(ctx); // clean up allocated class instances
soap_end(ctx); // clean up allocated temporaries
soap_free(ctx); // delete context
The ctx gSOAP engine context (type struct&soap) controls settings
and holds state, such as XML formatting, (e.g. SOAP_XML_INDENT),
serialization options, current state, and I/O settings. Simply set the output
stream (std::ostream) ctx-&os of the context to redirect the
content, e.g. to a file or string. Also, when serializing a graph rather than an XML tree (SOAP_XML_TREE option forces trees) the XML output conforms to SOAP encoding for object graphs based on id-ref, see Section& for details.
To read the XML representation from standard input into a book object, use:
soap *ctx = soap_new1(SOAP_XML_STRICT); // new context with option
if&(soap_read_book(ctx, &bk) != SOAP_OK)
&&&... error ...
&&&cout && bk.isbn && ", " && bk.title && ", " && bk.publisher &&
... further use of bk ...
soap_destroy(ctx); // delete deserialized objects
soap_end(ctx); // delete temporaries
soap_free(ctx); // delete context
Automatic built-in strict XML validation (enabled with SOAP_XML_STRICT)
ensures that data members are present so we can safely print them in this
example, thus ensuring consistency of data with the XML schema. Set the
ctx-&is input stream to read from a file/string stream
instead of stdin.
The soap_destroy and soap_end calls deallocate the deserialized
content, so use with care. In general, memory management is automatic in gSOAP
to avoid leaks.
The above uses a very simple example schema. The gSOAP toolkit handles all XML schema constructs defined by the XML schema standard. The toolkit is also able to (de)serialize pointer-based C/C++
data structures (including cyclic graphs), structs/classes, unions, enums, STL
containers, and even special data types such as struct tm. Therefore, the toolkit works in two directions: from WSDL/schema to C/C++ and from C/C++ to WSDL/schema.
The gSOAP toolkit also handles multiple schemas defined in multiple namespaces. Normally the namespace prefixes of XML namespaces are added to the C/C++ type
definitions to ensure type uniqueness. For example, if we would combine two
schemas in the same application where both schemas define a book object,
we need to resolve this conflict. In gSOAP this is done using namespace
prefixes, rather than C++ namespaces (research has pointed out that XML
namespaces are not equivalent to C++ namespaces). Thus, the book class
might actually be bound to an XML namespace and the class would be named
ns__book, where ns is bound to the corresponding namespace.
The following options are available to control serialization:
soap->encodingStyle = NULL; // to remove SOAP 1.1/1.2 encodingStyle
soap_mode(soap, SOAP_XML_TREE); // XML without id-ref (no cycles!)
soap_mode(soap, SOAP_XML_GRAPH); // XML with id-ref (including cycles)
soap_set_namespaces(soap, struct&Namespace *nsmap); //to set xmlns bindings
Other flags can be used to format XML, see Section&.
For more details on XML databinding support for C and C++, see
&&Feature Overview
The highlights of gSOAP are:
Unique interoperability features: the tools generate type-safe SOAP marshalling
routines to (de)serialize native and user-defined C and C++ data structures.
Support WSDL 1.1, WSDL 2.0, REST, SOAP 1.1, SOAP 1.2, SOAP RPC encoding style, and document/literal style.
gSOAP is one of the few SOAP toolkits that support the full range of SOAP 1.1
RPC encoding features including sparse multi-dimensional arrays and polymorphic
types. For example, a service operation with a base class parameter may accept
derived class instances from a client. Derived class instances keep their
identity through dynamic binding. The toolkit also supports all XSD
1.0 and 1.1 schema type constructs and has been tested against the W3C XML
Schema Patterns for Databinding Interoperability working group and of gSOAP
release 2.8.x passes all tests.
Supports WS-Security, WS-Addressing, WS-ReliableMessaging, C14N exclusive
canonicalization. The protocols are implemented using code generation with
wsdl2h and soapcpp2. The gSOAP tools can be used to generate messaging
protocols for other WS-* protocols.
gSOAP supports XML-RPC and RSS protocols. Examples are provided.
JSON support is included in the XML-RPC library to switch between XML-RPC
and JSON protocols. For more details, see the samples/xml-rpc-json folder in the package.
The wsdl2h tool supports WS-Policy. Policy assertions are included in
the generated service description header file with recommendations and usage
gSOAP supports MIME (SwA), DIME, and MTOM attachments and has streaming
capabilities to direct the data stream to/from resources.
gSOAP is the only toolkit that supports streaming MIME, DIME, and MTOM
attachment transfers, which allows you to exchange binary data of practically
unlimited size in the fastest possible way (streaming) while ensuring the
usefulness of XML interoperability.
gSOAP supports SOAP-over-UDP.
gSOAP supports IPv4 and IPv6.
gSOAP supports Zlib deflate and gzip compression (for HTTP, TCP/IP, and XML file storage).
gSOAP supports SSL (HTTPS) using OpenSSL and optionally using GNUTLS.
gSOAP supports HTTP/1.0, HTTP/1.1 keep-alive, chunking, basic authentication, and digest authentication using a plugin.
gSOAP supports SOAP one-way messaging.
The schema-specific XML pull parser is fast and efficient and does not require intermediate data storage for
demarshalling to save space and time.
The soapcpp2 compiler includes a WSDL and schema generator for convenient
Web Service publishing.
The soapcpp2 compiler generates sample input and output messages
for verification and testing (before writing any code). An option (-T)
can be used to automatically implement echo message services for testing.
The wsdl2h tool converts WSDL and XSD files to gSOAP header files for automated client and server development.
Generates source code for stand-alone Web Services and client applications.
Ideal for small devices such as Palm OS, Symbian, Pocket PC, because the memory footprint is small.
Ideal for building web services that are compute-intensive and are therefore best written in C and C++.
Platform independent: Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian, VXWorks, etc.
Supports serializing of application's native C and C++ data structures, which allows you to save and load XML serialized data structures to and from files.
Selective input and output buffering is used to increase efficiency, but full message buffering to determine HTTP message length
is not used. Instead, a three-phase serialization method is used to determine message length. As a result, large data sets
such as base64-encoded images can be transmitted with or without DIME attachments by small-memory devices such as PDAs.
Supports C++ single class inheritance, dynamic binding, overloading, arbitrary pointer structures such as lists, trees, graphs,
cyclic graphs, fixed-size arrays, (multi-dimensional) dynamic arrays, enumerations, built-in XSD Schema types including
base64Binary encoding, and hexBinary encoding.
No need to rewrite existing C/C++ applications for Web service deployment. However, parts of an application that use unions,
pointers to sequences of elements in memory, and void* need to be modified, but only if the data structures that
adopt them are required to be serialized or deserialized as part of a service operation invocation.
Three-phase marshalling: 1) analysis of pointers, single-reference, multi-reference, and cyclic data structures, 2) HTTP
message-length determination, and 3) serialization as per SOAP 1.1 encoding style or user-defined encoding styles.
Two-phase demarshalling: 1) SOAP parsing and decoding, which involves the reconstruction of multi-reference and cyclic data
structures from the payload, and 2) resolution of "forward" pointers (i.e. resolution of the forward href attributes in SOAP).
Full and customizable SOAP Fault processing (client receive and service send).
Customizable SOAP Header processing (send and receive), which for example enables easy transaction processing for the service to
keep state information.
&&Notational Conventions
The typographical conventions used by this document are:
Sans serif or italics font
denotes C and C++ source code, file names, and shell/batch commands.
denotes C and C++ keywords.
Courier font
denotes HTTP header content, HTML, XML, XML Schema content and WSDL content.
[Optional]
denotes an optional construct.
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in RFC-2119.
&&Differences Between gSOAP Versions 2.4 (and Earlier) and 2.5
To comply with WS-I Basic Profile 1.0a, gSOAP 2.5 and higher adopts SOAP document/literal by default.
There is no need for concern, because the WSDL parser wsdl2h automatically takes care of the differences when you provide a WSDL document, because SOAP RPC encoding, literal, and document style are supported.
A new soapcpp2 compiler option was added -e for backward compatibility with gSOAP 2.4 and earlier to adopt SOAP RPC encoding by default in case you want to develop a service that uses SOAP encoding. You can also use the gSOAP soapcpp2 compiler directives to specify SOAP encoding for individual operarations, when desired.
&&Differences Between gSOAP Versions 2.1 (and Earlier) and 2.2
You should read this section only if you are upgrading from gSOAP 2.1 to 2.2 and later.
Run-time options and flags have been changed to enable separate recv/send
settings for transport, content encodings, and mappings.
The flags are divided
into four classes: transport (IO), content encoding (ENC), XML marshalling
(XML), and C/C++ data mapping (C).
The old-style flags soap_disable_X
and soap_enable_X, where X is a particular feature, are
deprecated.
See Section& for more details.
&&Differences Between gSOAP Versions 1.X and 2.X
You should read this section only if you are upgrading from gSOAP 1.X to 2.X.
gSOAP versions 2.0 and later have been rewritten based on versions 1.X.
gSOAP 2.0 and later is thread-safe, while 1.X is not.
All files in the gSOAP 2.X distribution are renamed to avoid confusion with gSOAP version 1.X files:
gSOAP 1.X gSOAP 2.X
soapcpp.exe soapcpp2.exe
stdsoap.h stdsoap2.h
stdsoap.c stdsoap2.c
stdsoap.cpp stdsoap2.cpp
Changing the version 1.X application codes to accommodate gSOAP 2.X does not require a significant amount of recoding.
The change to gSOAP 2.X affects all functions defined in stdsoap2.c[pp] (the gSOAP runtime context API) and the functions in the
sources generated by the gSOAP soapcpp2 compiler (the gSOAP RPC+marshalling API).
Therefore, clients and services developed with gSOAP 1.X need to be modified to accommodate a change in the calling convention used in 2.X:
In 2.X, all gSOAP functions (including the service operation proxy routines) take an additional parameter which is an instance of the gSOAP runtime
context that includes file descriptors, tables, buffers, and flags.
This additional parameter is always the first parameter of any gSOAP function.
The gSOAP runtime context is stored in a struct&soap type. A struct was chosen to support application development in
C without the need for a separate gSOAP implementation.
An object-oriented approach with a class for the gSOAP runtime context would have prohibited the implementation of pure C applications.
Before a client can invoke service operations or before a service can accept requests, a runtime context needs to be allocated and
initialized.
Three new functions are added to gSOAP 2.X:
Function Description
soap_init(struct&soap *soap) Initializes a context (required only once)
struct&soap *soap_new() Allocates, initializes, and returns a pointer to a runtime context
struct&soap *soap_copy(struct&soap *soap) Allocates a new runtime context and copies contents of
the context such that the new environment does not share any data
with the original context
A context can be reused as many times as necessary and does not need to be
reinitialized in doing so. A dynamically allocated context is deallocated
with soap_free.
A new context is only required for each new thread to guarantee exclusive access
to a new runtime context by each thread.
For example, the following code stack-allocates the runtime context which is used for multiple service operation calls:
int&main()
&&&struct&
&&&soap_init(&soap); // initialize runtime context
&&&soap_call_ns__method1(&soap, ...); // make a remote call
&&&soap_call_ns__method2(&soap, ...); // make another remote call
&&&soap_destroy(&soap); // remove deserialized class instances (C++ only)
&&&soap_end(&soap); // clean up and remove deserialized data
&&&soap_done(&soap); // detach context (last use and no longer in scope)
The runtime context can also be heap allocated:
int&main()
&&&struct&soap *
&&&soap = soap_new(); // allocate and initialize runtime context
&&&if&(!soap) // couldn't allocate: stop
&&&soap_call_ns__method1(soap, ...); // make a remote call
&&&soap_call_ns__method2(soap, ...); // make another remote call
&&&soap_destroy(soap); // remove deserialized class instances (C++ only)
&&&soap_end(soap); // clean up and remove deserialized data
&&&soap_free(soap); // detach and free runtime context
A service needs to allocate and initialize an context before calling soap_serve:
int&main()
&&&struct&
&&&soap_init(&soap);
&&&soap_serve(&soap);
Or alternatively:
int&main()
&&&soap_serve(soap_new());
The soap_serve dispatcher handles one request or multiple requests when HTTP keep-alive is enabled (with the SOAP_IO_KEEPALIVE flag see Section&).
A service can use multi-threading to handle requests while running some other code that invokes service operations:
int&main()
&&&struct&soap soap1, soap2;
&&&pthread_
&&&soap_init(&soap1);
&&&if&(soap_bind(&soap1, host, port, backlog)
0) exit(1);
&&&if&(soap_accept(&soap1)
0) exit(1);
&&&pthread_create(&tid, NULL, (void*(*)(void*))soap_serve, (void*)&soap1);
&&&soap_init(&soap2);
&&&soap_call_ns__method(&soap2, ...); // make a remote call
&&&soap_end(&soap2);
&&&pthread_join(tid, NULL); // wait for thread to terminate
&&&soap_end(&soap1); // release its data
In the example above, two runtime contexts are required.
In comparison, gSOAP 1.X statically allocates the runtime context, which prohibits multi-threading (only one thread can invoke
service operations and/or accept requests due to the single runtime context).
Section& presents a multi-threaded stand-alone Web Service that handles multiple SOAP requests by spawning a thread for each request.
&&Interoperability
gSOAP interoperability has been verified with the following SOAP implementations and toolkits:
Apache 2.2
Apache Axis
Cape Connect
easySOAP++
Iona XMLBus
SOAP::Lite
White Mesa
&&Quick User Guide
This user guide offers a quick way to get started with gSOAP.
This section
requires a basic understanding of the SOAP protocol and some familiarity
with C and/or C++. In principle, SOAP clients and SOAP Web services can be
developed in C and C++ with the gSOAP soapcpp2 compiler without a detailed understanding
of the SOAP protocol when gSOAP client-server applications are built as an
ensamble and only communicate within this group (i.e.&meaning that you don't
have to worry about interoperability with other SOAP implementations).
section is intended to illustrate the implementation of gSOAP Web services and
clients that connect to and interoperate with other SOAP implementations such
as Apache Axis, SOAP::Lite, and .NET.
This requires some details of the SOAP
and WSDL protocols to be understood.
&&How to Build SOAP/XML Clients
In general, the implementation of a SOAP client application requires a
stub (also called service proxy) for each service operation that the client invokes. The primary stub's responsibility is to marshall the parameter data,
send the request with the parameters to the designated SOAP service over the
wire, to wait for the
response, and to demarshall the parameter data of the response when it arrives. The client
application invokes the stub routine for a service operation as if it would invoke
a local function. To write a stub routine in C or C++ by hand is a tedious task,
especially if the input and/or output parameters of a service operation contain
elaborate data structures such as objects, structs, containers, arrays, and pointer-linked graph structures. Fortunately, the
gSOAP wsdl2h WSDL parser tool and soapcpp2 stub/skeleton and serialization code generator tool automate the
development of SOAP/XML Web service client and server applications.
The soapcpp2 tool generates the necessary gluing code (also called stubs and skeletons) to build web service clients and services. The input to the soapcpp2
tool consists of an service definition-annotated C/C++ header file. The
header file can be generated from a WSDL (Web Service Description Language)
documentation of a service with the gSOAP wsdl2h WSDL parser tool.
Consider the following command (entered at the Linux/Unix/Windows command line prompt):
wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
This generates the file Web service description calc.h in an annotated C++ header file.
The WSDL specification (possibly consisting of multiple imported WSDL files and XSD schema files) is mapped to C++ using C++ databindings for
SOAP/XML. The generated header file contains data types and messages to operate
the service, and meta information related to WSDL and XML schemas.
To generate a service definition header file to develop a pure C client application, use the -c option:
wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
For more details on the WSDL parser and its options, see&.
The service definition calc.h header file is further processed by the
gSOAP soapcpp2 compiler to generate the gluing code's logic to invoke
the Web service from a client.
Looking into the file calc.h we see that the SOAP service methods are
specified as function prototypes. For example, the add function to add two double floats:
int&ns2__add(double&a, double&b, double& result);
The ns2__add function uses an XML namespace prefix to distinguish it
from operations defined in other namespaces, thus preventing name clashes. The
convention to add an XML namespace prefix to the names of operations, types,
and struct and class members is universally used by the gSOAP
tools and automatically created by wsdl2h, but it is not mandatory when
translating existing C/C++ types and operations to web services. Thus, the
prefix notation can be omitted from type names defined in an header file with
to run soapcpp2 to create clients and services that exchange existing
(i.e.&application-native) data types.
These function prototypes are translated by the gSOAP soapcpp2 tool to stubs and proxies for remote calls:
soapStub.h annotated copy of the input definitions
soapH.h serializers
soapC.cpp serializers
soapClient.cpp client calling stubs
Thus, the logic of the generated stub routines allow C and
C++ client applications to seamlessly interact with existing SOAP Web services as illustrated by the client code example in the next section.
The input and output parameters of a SOAP service operation may be primitive data
types or complex compound data types such as containers and pointer-based linked data structures. These are defined in the header file that is either generated by the WSDL parser or specified by hand.
The gSOAP soapcpp2 tool automatically generates
XML serializers and XML deserializers for the data types to enable the generated
stub routines to encode and decode the contents of the parameters of the service operations
in SOAP/XML.
Note that the gSOAP soapcpp2 tool also generates skeleton
routines soapServer.cpp for each of the service operations specified in the header file. The
skeleton routines
can be readily used to implement one or more of the service operations in a new
SOAP Web service. These skeleton routines are not used for building SOAP
clients in C++, although they can be used to build mixed SOAP client/server
applications (peer applications).
The add service operation (declared in the calc.h file obtained
with the wsdl2h tool in the previous section) adds two float values.
The WSDL description of the service provides the endpoint to invoke the service operations and the XML namespace used by the operations:
Endpoint URL: http://websrv.cs.fsu.edu/&engelen/calcserver.cgi
XML namespace: urn:calc
Each service operation has a SOAP action, which is an optional string to
identify the operation (mainly used with WS-Addressing), an operation request
message and a response message. The request and response messages for SOAP
RPC-encoded services are simply represented by C functions with input and
output parameters. For the add operation, the SOAP binding details are:
SOAP style: RPC
SOAP encoding: encoded
SOAP action: "" (empty string)
This information is translated to the wsdl2h-generated header file with the service definitions.
The calc.h header file for C++ generated by wsdl2h contains the following directives and declarations:
(the actual contents may vary depending on the release version and the options used to control the output):
//gsoap ns2 service name:
//gsoap ns2 service type:
calcPortType
//gsoap ns2 service port:
http://websrv.cs.fsu.edu/&engelen/calcserver.cgi
//gsoap ns2 service namespace:
//gsoap ns2 service method-protocol:
//gsoap ns2 service method-style:
//gsoap ns2 service method-encoding:
add http://schemas.xmlsoap.org/soap/encoding/
//gsoap ns2 service method-action:
int&ns2__add(double&a, double&b, double& result);
The other calculator operations are similar and elided here for clarity.
The //gsoap directives are required for the
soapcpp2 tool to generate code that is compliant to the SOAP protocol. For this service the SOAP protocol with the common "RPC encoding style" is used. For //gsoap directive details, see Section&.
The service operations are declared as
function prototypes, with all non-primitive parameter types needed by the
operation declared in the header file (all parameter types are primitive in
this case).
The calculator add operation takes two double floats a and b,
and returns the sum in result. By convention, all parameters are input
parameters except the last. The last parameter is always the output parameter.
A struct or class is used to wrap multiple output parameters, see
also Section&. This last parameter must be a pointer or
reference. By contrast, the input parameters support pass by value or by
pointer, but not pass by C++ reference.
The function prototype associated with a service operation always returns an
int. The value indicates success (0 or equivalently
SOAP_OK) or failure (any nonzero value). See Section&
for the nonzero error codes.
The role of the namespace prefix (ns2__) in the service operation name in the
function prototype declaration is discussed in detail in&.
Basically, a namespace prefix is added to a function name or type name with a pair of underscores,
as in ns2__add, where ns2 is the
namespace prefix and add is the service operation name. This mechanism ensures uniqueness of operations and types associated with a service.
It is strongly recommended to set the namespace prefix to a name of your
choice. This avoids problems when running wsdl2h on multiple WSDLs where
the sequence of prefixes ns1, ns2, and so on are arbitrarily
assigned to the services. To choose a prefix name for all the operations and types of a service, say prefix c__ for the calculator service, add the following line to typemap.dat:
c = "urn:calc"
and rerun wsdl2h. The typemap.dat configures wsdl2h to use
specific bindings and data types for services. The result is that c__add is used to uniquely identify the operation rather than the more arbitrary name ns2__add.
Note on the use of underscores in names: a single
underscore in an identifier name will be translated into a dash in XML, because
dashes are more frequently used in XML compared to underscores, see
Next, the gSOAP soapcpp2 tool is invoked from the command line to process the calc.h service definitions:
soapcpp2 calc.h
The tool generates the stub routines for the service operations.
Stub routines can be invoked
by a client program to invoke the remote service operations.
The interface of the generated stub routine is identical to the function prototype in the calc.h service defintion file, but with additional parameters to pass the gSOAP engine's runtime context soap, an endpoint URL (or NULL for the default), and a SOAP action (or NULL for the default):
int&soap_call_c__add(struct&soap *soap, char&*URL, char&*action, double&a, double&b, double& result);
This stub routine is saved in soapClient.cpp. The file soapC.cpp
contains the serializer and deserializer routines for the data
types used by the stub. You can use option -c for the soapcpp2 tool to
generate pure C code, when needed.
Note: the soap parameter must be a valid pointer to a gSOAP runtime
context. The URL can be set to override the default endpoint address (the endpoint defined by the WSDL).
The action parameter can be set to override the default SOAP action.
The following example C/C++ client program uses the stub:
#include "soapH.h" // include all interfaces (library and generated)
#include "calc.nsmap" // import the generated namespace mapping table
int&main()
&&&double&
&&&struct& // the gSOAP runtime context
&&&soap_init(&soap); // initialize the context (only once!)
&&&if&(soap_call_c__add(&soap, NULL, NULL, 1.0, 2.0, &sum) == SOAP_OK)
&&&&&&std::cout
&&&else&// an error occurred
&&&&&&soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
&&&soap_destroy(&soap); // delete deserialized class instances (for C++)
&&&soap_end(&soap); // remove deserialized data and clean up
&&&soap_done(&soap); // detach the gSOAP context
&&&return&0;
The call returns SOAP_OK (zero) on success and a nonzero error on
When an error occurred the fault is displayed with the
soap_print_fault function. Use soap_sprint_fault(struct&soap*,
char&*buf, size_t len) to print the error to a string, and use soap_stream_fault(struct&soap*, std::ostream&) to send it to a stream (C++ only).
The following functions can be used to explicitly setup a gSOAP runtime context (struct&soap):
Function Description
soap_init(struct&soap *soap) Initializes a runtime context
soap_init1(struct&soap *soap, soap_mode iomode) Initializes a runtime context and set in/out mode flags
soap_init2(struct&soap *soap, soap_mode imode, soap_mode omode) Initializes a runtime context and set in/out mode flags
struct&soap *soap_new() Allocates, initializes, and returns a pointer to a runtime context
struct&soap *soap_new1(soap_mode iomode) Allocates, initializes, and returns a pointer to a runtime context and set in/out mode flags
struct&soap *soap_new2(soap_mode imode, soap_mode omode) Allocates, initializes, and returns a pointer to a runtime context and set in/out mode flags
struct&soap *soap_copy(struct&soap *soap) Allocates a new runtime context and copies a context (deep copy, i.e.&the new context does not share any data with the other context)
soap_done(struct&soap *soap) Reset, close communications, and remove callbacks
soap_free(struct&soap *soap) Reset and deallocate the context created with soap_new or soap_copy
A runtime context can be reused as many times as necessary for client-side remote calls and does not need to be reinitialized in doing so.
A new context is required for each new thread to guarantee exclusive access
to runtime context by threads.
Also the use of any client calls within an active service method requires a new context.
The soapcpp2 code generator tool also generates a service proxy class for C++ client applications (and service objects for server applications) with the -i (or -j) option:
soapcpp2 -i calc.h
The proxy is defined in:
soapcalcProxy.h client proxy class
soapcalcProxy.cpp client proxy class
Note: without the -i option only old-style service proxies and objects
are generated, which are less flexible and no longer recommended. Use -j
as an alternative to -i to generate classes with the same functionality,
but that are not inherited from struct&soap and use a pointer to a
struct&soap engine context that can be shared with other proxy and
service class instances. This choice is also important when services are chained, see Section&.
The generated C++ proxy class initializes the gSOAP runtime context and offers the service interface as a collection of methods:
#include "soapcalcProxy.h" // get proxy
#include "calc.nsmap" // import the generated namespace mapping table
int&main()
&&&calcProxy calc(SOAP_XML_INDENT);
&&&double&
&&&if&(calc.add(1.0, 2.0, sum) == SOAP_OK)
&&&&&&std::cout
&&&&&&calc.soap_stream_fault(std::cerr);
&&&return&calc. // nonzero when error
The proxy class is derived from the gSOAP runtime context structure
struct&soap and thus inherits (option -i) all state information
of the runtime. The proxy constructor takes context mode parameters to initialize the context, e.g.&SOAP_XML_INDENT in this example.
The code is compiled and linked with soapcalcProxy.cpp, soapC.cpp,
and stdsoap2.cpp (or use libgsoap++.a).
The proxy class name is extracted from the WSDL content and may not always be in a short format. Feel free to change the entry
//gsoap ns2 service name: calc
and rerun soapcpp2 to generate code that uses the new name.
When the example client application is invoked, a SOAP request is performed:
POST /&engelen/calcserver.cgi HTTP/1.1
Host: websrv.cs.fsu.edu
User-Agent: gSOAP/2.7
Content-Type: text/ charset=utf-8
Content-Length: 464
Connection: close
SOAPAction: ""
&?xml version="1.0" encoding="UTF-8"?>
&SOAP-ENV:Envelope
&&&xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
&&&xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
&&&xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
&&&xmlns:xsd="http://www.w3.org/2001/XMLSchema"
&&&xmlns:c="urn:calc">
&&&&SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
&&&&&&&c:add>
&&&&&&&&&&a>1&/a>
&&&&&&&&&&b>2&/b>
&&&&&&&/c:add>
&&&&/SOAP-ENV:Body>
&/SOAP-ENV:Envelope>
The SOAP response message:
HTTP/1.1 200 OK
Date: Wed, 05 May :21 GMT
Server: Apache/2.0.52 (Scientific Linux)
Content-Length: 463
Connection: close
Content-Type: text/ charset=utf-8
&?xml version="1.0" encoding="UTF-8"?>
&SOAP-ENV:Envelope
&&&xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
&&&xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
&&&xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
&&&xmlns:xsd="http://www.w3.org/2001/XMLSchema"
&&&xmlns:ns="urn:calc">
&&&&SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
&&&&&&&ns:addResponse>
&&&&&&&&&&result>3&/result>
&&&&&&&/ns:addResponse>
&&&&/SOAP-ENV:Body>
&/SOAP-ENV:Envelope>
A client can invoke a sequence of service operations:
#include "soapcalcProxy.h" // get proxy
#include "calc.nsmap" // import the generated namespace mapping table
int&main()
&&&calcProxy calc(SOAP_IO_KEEPALIVE); // keep-alive improves connection performance
&&&double&sum = 0.0;
&&&double&val[] =
5.0, 3.5, 7.1, 1.2 ;
&&&for&(int&i = 0; i
&&&&&&if&(calc.add(sum, val[i], sum))
&&&&&&&&&return&calc.
&&&std::cout
&&&return&0;
In the above, no data is deallocated until the proxy is deleted. To deallocate deserialized data between the calls, use:
&&&for&(int&i = 0; i
&&&&&&if&(calc.add(sum, val[i], sum))
&&&&&&&&&return&calc.
&&&&&&calc.destroy();
Deallocation is safe here, since the float values were copied and saved in
sum. In other scenarios one must make sure data is copied or removed from
the deallocation chain with:
soap_unlink(struct&soap *soap, const&void&*data)
which is to be invoked on each data item to be preserved, before destroying deallocated data. When the proxy is deleted, also all deserialized data is deleted. To delegate deletion to another runtime context for later removal, use:
soap_delegate_deletion(struct&soap *soap_from, struct&soap *soap_to)
For example
soap_init(&soap);
{ // create proxy
&&&...&data generated ...
&&&soap_delegate_deletion(&calc, &soap);
} // proxy deleted
...&data used ...
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
In C (use wsdl2h -c) the example program would be written as:
#include "soapH.h"
#include "calc.nsmap"
int&main()
&&&struct&
&&&double&sum = 0.0;
&&&double&val[] =
5.0, 3.5, 7.1, 1.2 ;
&&&for&(i = 0; i
&&&soap_init1(&soap, SOAP_IO_KEEPALIVE);
&&&&&&if&(soap_call_c__add(&soap, NULL, NULL, sum, val[i], &sum))
&&&&&&&&&return&soap.
&&&printf("Sum = %lg\n", sum);
&&&soap_end(&soap);
&&&soap_done(&soap);
&&&return&0;
The code above is compiled and linked with soapClient.c, soapC.c,
and stdsoap2.c (or use libgsoap.a).
&&XML Namespace Considerations
The declaration of the ns2__add function prototype (discussed in the previous section) uses the namespace prefix
ns2__ of the service operation namespace, which is distinguished by a pair of underscores in the function name to
separate the namespace prefix from the service operation name.
The purpose of a namespace prefix is to associate a service
operation name with a service in order to prevent naming conflicts, e.g.&to distinguish identical service operation names used
by different services.
Note that the XML response of the service example uses a namespace prefix that may be different (e.g.&ns) as long as it bound to the same namespace name urn:calc through the xmlns:ns="urn:calc
The use of namespace prefixes and namespace names is also required to enable SOAP applications to validate the content of
SOAP messages.
The namespace name in the service response is verified by the stub routine by using the
information supplied in a namespace mapping table that is required to be part of gSOAP client and service application codes.
The table is accessed
at run time to resolve namespace bindings, both by the generated stub's data structure serializer for encoding the client request
and by the generated stub's data structure deserializer to decode and validate the service response. The namespace mapping table
should not be part of the header file input to the gSOAP soapcpp2 tool. Service details including namespace bindings may be provided with gSOAP directives in a header file, see Section&.
The namespace mapping table is:
struct&Namespace namespaces[] =
{&&&// {"ns-prefix", "ns-name"}
&&&{"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"}, // MUST be first
&&&{"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"}, // MUST be second
&&&{"xsi",
"http://www.w3.org/2001/XMLSchema-instance"}, // MUST be third
&&&{"xsd",
"http://www.w3.org/2001/XMLSchema"}, // 2001 XML Schema
&&&{"ns2",
"urn:calc"}, // given by the service description
&&&{NULL, NULL} // end of table
The first four namespace entries in the table consist of the standard namespaces used by the SOAP 1.1 protocol. In fact, the
namespace mapping table is explicitly declared to enable a programmer to specify the SOAP encoding style and to allow the
inclusion of namespace-prefix with namespace-name bindings to comply to the namespace requirements of a specific SOAP service. For
example, the namespace prefix ns2, which is bound to urn:calc by the namespace mapping table shown
above, is used by the generated stub routine to encode the add request. This is performed automatically by the gSOAP soapcpp2
tool by using the ns2 prefix of the ns2__add method name specified in the calc.h header file. In
general, if a function name of a service operation, struct name, class name, enum name, or field name of a
struct or class has a pair of underscores, the name has a namespace prefix that must be defined in the namespace
mapping table.
The namespace mapping table will be output as part of the SOAP Envelope by the stub routine. For example:
&SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
&&&xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
&&&xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
&&&xmlns:xsd="http://www.w3.org/2001/XMLSchema"
&&&xmlns:ns2="urn:calc"
&&&SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
The namespace bindings will be used by a SOAP service to validate the SOAP request.
The incorporation of namespace prefixes into C++ identifier names is necessary to distinguish service operations that
share the same name but are provided by separate Web services and/or
organizations. It avoids potential name clashes, while sticking to the C
syntax. The C++ proxy classes generated with soapcpp2 -i (or -j) drop the
namespace prefix from the method names
The namespace prefix convention is also be applied to non-primitive types. For example, class names are prefixed to avoid name clashes when the same name is used by multiple XML schemas. This ensures that the XML databinding never suffers from conflicting schema content. For example:
class&e__Address // an electronic address from schema 'e'
class&s__Address // a street address from schema 's'
The namespace prefix is separated from the name of a data type by a pair of underscores (__).
An instance of e__Address is encoded by the generated serializer for this type as an Address element with namespace prefix e:
&e:Address xsi:type="e:Address">
&&&&email xsi:type="string">me@home&/email>
&&&&url xsi:type="string">www.me.com&/url>
&/e:Address>
While an instance of s__Address is encoded by the generated serializer for this type as an Address element with namespace prefix s:
&s:Address xsi:type="s:Address">
&&&&street xsi:type="string">Technology Drive&/street>
&&&&number xsi:type="int">5&/number>
&&&&city xsi:type="string">Softcity&/city>
&/s:Address>
The namespace mapping table of the client program must have entries for e and s that refer to the XML Schemas of the data types:
struct&Namespace namespaces[] =
&&&{"e", "http://www.me.com/schemas/electronic-address"},
&&&{"s", "http://www.me.com/schemas/street-address"},
This table is required to be part of the client application to allow access by the serializers and deserializers of the data types at run time.
&&How to Generate C++ Client Proxy Classes
Proxy classes for C++ client applications are automatically generated by the gSOAP soapcpp2 tool, as was shown in Section&.
There is a new and improved code generation capability for proxy classes, which
is activated with the soapcpp2 -i (or j) option. These new proxy classes are
derived from the soap structure, have a cleaner interface and offer more
capabilites.
With C++, you can also use wsdl2h option -qname to generate
the proxy in a C++ namespace name. This is very useful if you want to
create multiple proxies for services by repeated use of wsdl2h and
combine them in one code.
Alternatively, you can run wsdl2h just once on
all service WSDLs and have soapcpp2 generate multiple proxies for you.
The latter approach does not use C++ namespaces and may reduce the overall
amount of code.
To illustrate the generation of a "standard" (old-style) proxy class, the
calc.h header file example of the previous section is augmented with
the appropriate directives to enable the gSOAP soapcpp2 tool to generate the proxy
class. Directives are included in the generated header file by the wsdl2h WSDL importer:
// Content of file "calc.h":
//gsoap ns2 service name: calc
//gsoap ns2 service port: http://websrv.cs.fsu.edu/&engelen/calcserver.cgi
//gsoap ns2 service protocol: SOAP1.1
//gsoap ns2 service style: rpc
//gsoap ns2 service encoding: encoded
//gsoap ns2 service namespace: urn:calc
//gsoap ns2 service method-protocol: add SOAP
//gsoap ns2 service method-style: add rpc
//gsoap ns2 service method-encoding: add encoded
//gsoap ns2 service method-action: add ""
int&ns2__add(double&a, double&b, double& result);
//gsoap ns2 service method-protocol: sub SOAP
//gsoap ns2 service method-style: sub rpc
//gsoap ns2 service method-encoding: sub encoded
//gsoap ns2 service method-action: sub ""
int&ns2__sub(double&a, double&b, double& result);
//gsoap ns2 service method-protocol: mul SOAP
//gsoap ns2 service method-style: mul rpc
//gsoap ns2 service method-encoding: mul encoded
//gsoap ns2 service method-action: mul ""
int&ns2__mul(double&a, double&b, double& result);
The first three directives provide the service details, which is used to name the proxy class, the service location port (endpoint), and
the XML namespace. The subsequent groups of three directives per method define the operation's SOAP style (RPC) and encoding (SOAP encoded), and SOAP action string.
These directives can be provided for each service operation when the SOAPAction is required, such as with SOAP1.1 RPC encoded and when WS-Addressing is used.
In this example, the service protocol is set by default for all operations to use SOAP 1.1 RPC encoding.
For //gsoap directive details, see Section&.
The soapcpp2 tool takes this header file and generates a proxy soapcalcProxy.h with the
following contents (not using option -i):
#include "soapH.h"
class&calc
&&&struct&soap *
&&&const&char&*
&&&calc() { ... };
&&&~calc() { ... };
&&&virtual&int&ns2__add(double&a, double&b, double& result) { return&soap ? soap_call_ns2__add(soap, endpoint, NULL, a, b, result) : SOAP_EOM; };
&&&virtual&int&ns2__sub(double&a, double&b, double& result) { return&soap ? soap_call_ns2__sub(soap, endpoint, NULL, a, b, result) : SOAP_EOM; };
&&&virtual&int&ns2__mul(double&a, double&b, double& result) { return&soap ? soap_call_ns2__mul(soap, endpoint, NULL, a, b, result) : SOAP_EOM; };
The gSOAP context and endpoint are declared public to enable access.
This generated proxy class can be included into a client application together with the generated namespace table as shown in this example:
#include "soapcalcProxy.h" // get proxy
#include "calc.nsmap"
// get namespace bindings
int&main()
&&&double&r;
&&&if&(s.ns2__add(1.0, 2.0, r) == SOAP_OK)
&&&&&&std::cout
&&&&&&soap_print_fault(s.soap, stderr);
&&&return&0;
The constructor allocates and initializes a gSOAP context for the instance.
You can use soapcpp2 option -n together with -p to create
a local namespaces table to avoid link conflicts when you need multiple
namespace tables or need to combine multiple clients, see also
Sections& and&, and you can use a C++ code
namespace to create a namespace qualified proxy class, see
The soapcpp2 -i option to generate proxy classes
derived from the base soap structure. In addition, these classes offer more
functionality as illustrated in Section&.
&&XSD Type Encoding Considerations
Many SOAP services require the explicit use of XML Schema types in the SOAP payload. The default encoding, which is also adopted
by the gSOAP soapcpp2 tool, assumes SOAP RPC encoding which only requires the use of types to handle polymorphic cases.
Nevertheless, the use of XSD typed messages is advised to improve interoperability.
XSD types are introduced with typedef definitions in
the header file input to the gSOAP soapcpp2 tool. The type name defined by a typedef definition corresponds to an XML Schema
type (XSD type). For example, the following typedef declarations
define various built-in XSD types implemented as primitive C/C++ types:
// Contents of header file:
typedef&char&*xsd__ // encode xsd__string value as the xsd:string schema type
typedef&char&*xsd__anyURI; // encode xsd__anyURI value as the xsd:anyURI schema type
typedef&float&xsd__ // encode xsd__float value as the xsd:float schema type
typedef&long&xsd__ // encode xsd__int value as the xsd:int schema type
typedef&bool&xsd__ // encode xsd__boolean value as the xsd:boolean schema type
typedef&unsigned&long&long&xsd__positiveI // encode xsd__positiveInteger value as the xsd:positiveInteger
schema type
This easy-to-use mechanism informs the gSOAP soapcpp2 tool to generate serializers and deserializers that explicitly encode and decode the
primitive C++ types as built-in primitive XSD types when the typedefed type is used in the parameter signature of a
service operation (or when used nested within structs, classes, and arrays).
At the same time, the use of typedef
does not force any recoding of a C++ client or Web service application as the internal C++ types used by the application
are not required to be changed (but still have to be primitive C++ types, see Section& for alternative class
implementations of primitive XSD types which allows for the marshalling of polymorphic primitive types).
Reconsider the calculator example, now rewritten with explicit XSD types to illustrate the effect:
// Contents of file "calc.h":
typedef&double&xsd__double;
int&ns2__add(xsd__string a, xsd__double b, xsd__double &Result);
When processed by the gSOAP soapcpp2 tool it generates source code for the function
soap_call_ns2__add, which is identical to the C-style SOAP call:
int&soap_call_ns2__add(struct&soap *soap, char&*URL, char&*action, double&a, double&b, double& result);
The client application does not need to be rewritten and can still call the proxy using the "old" C-style function signatures. In contrast to
the previous implementation of the stub however, the encoding and decoding of the data types by the stub has been changed to
explicitly use the XSD types in the message payload.
For example, when the client application calls the proxy, the proxy produces a SOAP request with an xsd:double (the xsi:type is shown when the soapcpp2 -t option is used):
&SOAP-ENV:Body>
&&&&ns2:add>
&&&&&&&a

我要回帖

更多关于 hive 客户端 协议 的文章

 

随机推荐