Update README
This commit is contained in:
@@ -1,13 +1,16 @@
|
|||||||
# csoap
|
# csoap
|
||||||
A lightweight C++ SOAP client library.
|
|
||||||
|
|
||||||
[中文版介绍](https://segmentfault.com/a/1190000009874151)
|
[中文版介绍](https://segmentfault.com/a/1190000009874151)
|
||||||
|
|
||||||
## Usage
|
A lightweight C++ SOAP client & server library based on Boost.Asio.
|
||||||
|
|
||||||
|
NOTE: The server part is currently under development, not stable enough to be used in a real production.
|
||||||
|
|
||||||
|
## Client Usage
|
||||||
|
|
||||||
Firstly, please install SoapUI if you don't have it. We need SoapUI to generate sample requests for each web service operation. The open source version is good enough.
|
Firstly, please install SoapUI if you don't have it. We need SoapUI to generate sample requests for each web service operation. The open source version is good enough.
|
||||||
|
|
||||||
Take the calculator web service provided by ParaSoft as an example. Download the WSDL from http://ws1.parasoft.com/glue/calculator.wsdl, create a SOAP project within SoapUI (remember to check "Create sample requests for all operations?"), you will see the sample request for "add" operation as the following:
|
Take the calculator web service provided by ParaSoft as an example. Download the WSDL from http://ws1.parasoft.com/glue/calculator.wsdl, create a SOAP project within SoapUI (remember to check "**Create sample requests for all operations?**"), you will see the sample request for "add" operation as the following:
|
||||||
```xml
|
```xml
|
||||||
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
|
||||||
<soapenv:Header/>
|
<soapenv:Header/>
|
||||||
@@ -20,72 +23,96 @@ Take the calculator web service provided by ParaSoft as an example. Download the
|
|||||||
</soapenv:Envelope>
|
</soapenv:Envelope>
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to call the "add" operation, we have to send a HTTP request with the above SOAP envelope as the content. Let's see how to do this with csoap.
|
In order to call the "add" operation, we have to send a HTTP request with the above SOAP envelope as the content. Let's see how to do this with *csoap*.
|
||||||
|
|
||||||
|
Firstly, create a class `CalculatorClient` which is derived from `csoap::SoapClient`:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
bool Add() {
|
#include <string>
|
||||||
// Create a SOAP request.
|
#include "csoap/soap_client.h"
|
||||||
csoap::SoapRequest soap_request("add");
|
|
||||||
|
|
||||||
// Set the service namespace.
|
class CalculatorClient : public csoap::SoapClient {
|
||||||
csoap::Namespace service_ns = { "cal", "http://www.parasoft.com/wsdl/calculator/" };
|
public:
|
||||||
soap_request.set_service_ns(service_ns);
|
CalculatorClient() {
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
// Add parameters for the operation.
|
Initialize the URL, host, port, etc. in `Init()`:
|
||||||
soap_request.AddParameter("x", "1.0");
|
```cpp
|
||||||
soap_request.AddParameter("y", "2.0");
|
private:
|
||||||
|
void Init() {
|
||||||
|
url_ = "/glue/calculator";
|
||||||
|
host_ = "ws1.parasoft.com";
|
||||||
|
port_ = ""; // Default to "80".
|
||||||
|
service_ns_ = { "cal", "http://www.parasoft.com/wsdl/calculator/" };
|
||||||
|
result_name_ = "Result";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Because four calculator operations (*add*, *subtract*, *multiply* and *divide*) all have two parameters, we create a wrapper for `SoapClient::Call()`, name is as `Calc`:
|
||||||
|
```cpp
|
||||||
|
bool Calc(const std::string& operation,
|
||||||
|
const std::string& x_name,
|
||||||
|
const std::string& y_name,
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
double* result) {
|
||||||
|
// Prepare parameters.
|
||||||
|
csoap::Parameter parameters[] = {
|
||||||
|
{ x_name, x },
|
||||||
|
{ y_name, y }
|
||||||
|
};
|
||||||
|
|
||||||
// Generate the XML string for the SOAP envelope.
|
// Make the call.
|
||||||
std::string http_request_body;
|
std::string result_str;
|
||||||
soap_request.ToXmlString(&http_request_body);
|
if (!Call(operation, parameters, 2, &result_str)) {
|
||||||
|
|
||||||
// Create a HTTP request.
|
|
||||||
csoap::HttpRequest http_request(csoap::kHttpV11);
|
|
||||||
|
|
||||||
// Set the HTTP request headers.
|
|
||||||
http_request.set_url("/glue/calculator");
|
|
||||||
http_request.set_content_length(http_request_body.size());
|
|
||||||
http_request.set_host("ws1.parasoft.com", "");
|
|
||||||
http_request.set_soap_action("add");
|
|
||||||
|
|
||||||
// Send the HTTP request and get the HTTP response.
|
|
||||||
|
|
||||||
csoap::HttpResponse http_response;
|
|
||||||
|
|
||||||
csoap::HttpClient http_client;
|
|
||||||
csoap::ErrorCode ec = http_client.SendRequest(http_request,
|
|
||||||
http_request_body,
|
|
||||||
&http_response);
|
|
||||||
|
|
||||||
// Error handling.
|
|
||||||
if (ec != csoap::kNoError) {
|
|
||||||
std::cerr << csoap::GetErrorMessage(ec) << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the SOAP response.
|
// Convert the result from string to double.
|
||||||
std::string result;
|
try {
|
||||||
csoap::SoapResponse soap_response;
|
*result = boost::lexical_cast<double>(result_str);
|
||||||
if (!soap_response.Parse(http_response.content(), "addResponse", "Result", &result)) {
|
} catch (boost::bad_lexical_cast&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << result << std::endl;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
It's not that complicated. But you can't code like this for each operation. You have to do some encapsulation, make a general function, add a base class, and so on. Check the "demo" folder for the detailed example.
|
Finally, we implement the four operations simply as the following:
|
||||||
|
```cpp
|
||||||
|
bool Add(double x, double y, double* result) {
|
||||||
|
return Calc("add", "x", "y", x, y, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Subtract(double x, double y, double* result) {
|
||||||
|
return Calc("subtract", "x", "y", x, y, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Multiply(double x, double y, double* result) {
|
||||||
|
return Calc("multiply", "x", "y", x, y, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Divide(double x, double y, double* result) {
|
||||||
|
return Calc("divide", "numerator", "denominator", x, y, result);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
See? It's not that complicated. Check folder ***demo/calculator_client*** for the full example.
|
||||||
|
|
||||||
|
## Server Usage
|
||||||
|
TODO
|
||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
- Only support HTTP 1.1.
|
|
||||||
- Only support `int`, `double`, `bool` and `string` parameters.
|
- Only support `int`, `double`, `bool` and `string` parameters.
|
||||||
- Only support UTF-8 encoded content.
|
- Only support UTF-8 encoded content.
|
||||||
|
- One connection one call.
|
||||||
|
- Connection is in synchronous (or blocking) mode; timeout (default to 30s) is configurable.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- The TCP socket client is based on Boost.Asio.
|
- Boost.Asio is used for both client and server.
|
||||||
- The XML parsing is based on TinyXml or PugiXml, a macro `CSOAP_USE_TINYXML` controls which one to use.
|
- XML processing is based on PugiXml, which is already included in the source tree.
|
||||||
- Build system is CMake, but it should be easy to integrate into your project.
|
- Build system is CMake, but it should be quite easy to integrate into your own project.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "csoap/soap_client.h"
|
#include "csoap/soap_client.h"
|
||||||
|
|
||||||
class CalculatorClient : csoap::SoapClient {
|
class CalculatorClient : public csoap::SoapClient {
|
||||||
public:
|
public:
|
||||||
CalculatorClient();
|
CalculatorClient();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user