gSOAP XML-RPC and JSON
2.8 Stable
|
XML-RPC is a simple and effective messaging protocol. XML-RPC uses a generic XML format to compose XML messages for platform-neutral data exchange. XML-RPC serialization proceeds by marshaling parameters in predefined XML elements. A simple type system is provided to cover primitive types, structs, and arrays. That is, XML-RPC defines a collection of frequently used XML types with common programming language equivalents. XML-RPC does NOT provide a data binding to XML and does NOT support a validation mechanism to ensure that data content is validated against a data type or schema.
See http://www.xmlrpc.com for more details.
JSON (JavaScript Object Notation) is an even simpler data format to support platform-neutral data interchange that is highly compatible across programming languages.
See http://www.json.org for more details.
XML-RPC and JSON data is largely interchangeable in this implementation. That is, XML-RPC data can be converted to/from JSON data by simply choosing the XML-RPC or the JSON serializer. Data is interchangeable with the exception of XML-RPC dateTime and XML-RPC base64-encoded data that have no JSON equivalents. Also, JSON only supports floats. Ints are converted to double floats by the JSON serializer. Developers should be aware of these limitations as a JSON receiver will never receive an int value, dateTime, and base64 raw data. This implementation sends ints as floats and dateTime and base64 data as string type content in JSON.
The following source files are provided for XML-RPC support in C++:
xml-rpc.cpp
: C++ XML-RPC implementation and data managementxml-rpc-io.h
: C++ XML-RPC data serialization over streamsxml-rpc-io.cpp
: C++ XML-RPC data serialization over streamsxml-rpc-iters.h
: C++ iterators for structs, arrays, and parametersxml-rpc.h
: XML-RPC binding as a gSOAP .h file for soapcpp2 (do not #include this file in your project builds)For JSON serialization in C++, use the following files:
json.h
: C++ JSON serializer over streamsjson.cpp
: C++ JSON serializer over streamsFor JSON-RPC over HTTP (JSON REST method), please use the plugin/httppost.c
plugin. See JSON-RPC over HTTP explanation below.
Auto-generated files: note that soapH.h
, soapStub.h
and soapC.cpp
are required for XML-RPC and JSON. To auto-generate these C++ files, execute:
soapcpp2 -CSL xml-rpc.h
Then compile and link these files together with stdsoap2.cpp
(or link with libgsoap++.a
installed by the gSOAP package).
Examples are provided in the software package:
xml-rpc-currentTime.cpp
: XML-RPC client in C++, also uses JSONxml-rpc-currentTimeServer.cpp
: XML-RPC server in C++xml-rpc-weblogs.cpp
: XML-RPC client in C++xml-rpc-json.cpp
: XML-RPC to/from JSON examplejson-currentTime.cpp
: JSON client in C++json-currentTimeServer.cpp
: JSON server in C++See xml-rpc.h
for the C++ member functions to create XML-RPC messages and decode responses. These functions provide intuitive type casts, assignments, and indexing operations.
An XML-RPC data value is created in C++ as follows, which requires a context ctx
for the engine state (the soap struct) for communication, and managed data allocation/deallocation:
Unicode can be stored in UTF8-formattted strings. For compatibility with XML-RPC serialization of UTF8-encoded strings, use the SOAP_C_UTFSTRING
flag.
The code shown above creates an empty value v
. It can be set by any one of the following assignments:
You can combine this syntax to create arrays of arrays, arrays of structs, and so on, for example:
which creates a singleton array containing a struct with two members: name
set to "bob"
and toys
set to an array containing "ball"
and "furby"
. In JSON format this is represented as:
[ { "name": "bob", "toys": ["ball", "furby"] } ] ^ ^ ^ ^ | | | | an array_/ | | | of 1 struct_/ | | with 2 members_/______________/
To check the type of a value, use the is_type
methods:
There are three additional methods to invoke on a value:
For example, given the value v
assigned the array shown above, we have:
To extract data we can use casts and array/struct indexing on a value v
as follows:
To access base64 binary raw data of a value v
, use:
To traverse arrays and structs, we should use iterators. An iterator has an index()
method to obtain the array index (an int) and struct member name (a string). Dereferencing the iterator gives the JSON value in the array or struct located at that index.
For example, to traverse a value v
that is an array or a struct:
Parameter lists are similar to arrays and its values are indexed. We can also iterate over parameter content of XML-RPC remote methods:
There are two additional methods to invoke on parameters:
All dynamically allocated memory that is internally used to store data is deallocated with:
A typical XML-RPC calling sequence in C++ is:
Alternatively when desired, the parameters of the methodCall object can be directly populated as follows:
Note that in the client code, after the response is retrieved, the implicit type casts done by assignments extract the values. These casts can be used anywhere to extract values:
Type casts can also be used to convert data, which means they never produce an exception. Casting to string (const char*)
converts atomic values and base64 data to strings, but does not convert compound types such as arrays and structs.
which prints a string representation of the int, double, boolean, time, or base64 values of parameters. An empty string is printed for arrays and structs. Use iterators to walk over arrays and structs to print values. Or use the JSON module to print values in JSON format, see further on JSON below.
A typical C++ XML-RPC server sequence is:
With option 1 the server code above uses standard in/out and thus runs over CGI. Other possibilities are given by options 2 and 3.
To serve requests at a port, we use the soap_bind()
and soap_accept()
calls to bind the server to a port and accept requests via socket, see also the docs and examples for these calls (e.g. samples/webserver.c):
To send and receive XML over streams, use xml-rpc-io.h
and xml-rpc-io.cpp
. For example:
which will display the data in XML-RPC format. To parse XML-RPC data from a stream, use:
To display values in JSON format or to parse JSON data, use the json.h and json.cpp JSON serializers in combination with xml-rpc.cpp and the auto-generated soapH.h and soapC.cpp. It is also possible to send and receive JSON data over HTTP as JSON-RPC operations, but this requires some more coding (see JSON-RPC over HTTP below).
Because the internal data is the same for XML-RPC and JSON, You can dump data in XML-RPC or in JSON format. You can also parse XML-RPC data and dump to JSON data and vice versa.
For example, we can parse a JSON-formatted string and use that data to make an XML-RPC call:
The JSON protocol has fewer data types than XML-RPC, so type information can be lost when serializing to JSON:
See the section on C++ Examples on how to populate and extract C++ data.
Strings are stored and exchanged in UTF8 format in 8-bit strings (char*
and std::string
) by using the SOAP_C_UTFSTRING
flag. Without this flag, 8-bit strings are converted to UTF8. By contrast, wide character strings use unicode.
To force reading and writing JSON in ISO 8859-1 format from UTF8 strings, use the SOAP_ENC_LATIN
flag to set the context.
To invoke JSON-RPC over HTTP on the client side, use json_call
:
To implement a JSON-RPC server for CGI (e.g. install in cgi-bin):
For client and server examples, please see the gSOAP package content:
gsoap/samples/xml-rpc-json/json-currentTime.cpp
gsoap/samples/xml-rpc-json/json-currentTimeServer.cpp
The following source files are provided for XML-RPC support in C:
xml-rpc.h
: XML-RPC binding as a gSOAP .h file for soapcpp2 (do not #include this file in your project builds)For JSON serialization, use the following files instead of xml-rpc-io.h and xml-rpc-io.cpp:
json_c.h
: C JSON serializerjson_c.c
: C JSON serializerFor JSON-RPC over HTTP (JSON REST method), please use the plugin/httppost.c
plugin. See JSON-RPC over HTTP explanation below.
Note that soapH.h
, soapStub.h
, and soapC.c
are required for XML-RPC and JSON. To generate these C files, you need to execute:
soapcpp2 -c -CSL xml-rpc.h
Also compile and link with stdsoap2.c
(or link with libgsoap.a
installed by the gSOAP package).
Examples are provided in the software package:
xml-rpc-currentTime.c
: client in Cxml-rpc-weblogs.c
: client in CAll XML-RPC and JSON message manipulation is done at a very low-level.
An XML RPC call is made using the following function that you can define for your convenience:
Then use this XML-RPC method caller in C as follows:
To dynamically allocate data for automatic deallocation by the gSOAP engine, use soap_malloc(ctx, size)
, for example as follows:
See xml-rpc-currentTime.c
and xml-rpc-weblogs.c
for example C code.
A convenient way to display XML RPC data can be implemented as follows:
To display values in JSON format or parse JSON data, use the json_c.h
and json_c.c
JSON serializers. It is also possible to send and receive JSON data over HTTP.
You can dump the XML-RPC data in JSON or populate XML-RPC from JSON data, because the data stored in C is independent of XML-RPC and JSON formats.
For example:
The JSON protocol has fewer data types than XML-RPC, so type information can be lost when serializing to JSON:
See the section on C++ Examples on how to populate and extract C++ data.
Strings are stored and exchanged in UTF8 format in 8-bit strings (char*
) by using the SOAP_C_UTFSTRING
flag. Without this flag, 8-bit strings are converted to UTF8. By contrast, wide character strings use unicode.
To force reading and writing JSON in ISO 8859-1 format from UTF8 strings, use the SOAP_ENC_LATIN
flag to set the context.
To serialize JSON over HTTP as a client application, use plugin/httppost.c
, for example: