linuxの下でgsoapを利用してwebservice通信方法の詳細を実現する
11830 ワード
gSOAPコンパイルツールはSOAP/XMLのC/C++言語に関する実現を提供し、データアクセスの他のプラットフォーム、例えばC#、JAVAが実現したいくつかのwebserviceサービスは、データを他の設備に接続する必要がある応用の中で、gSOAPは開発に大きな便利を提供することができる.
一般的に、wsdlファイル、アクセスurlアドレス、対応するフィールド定義ドキュメントが提供されるwebserviceサービス側は、gSOAPを使用してwebserviceドッキングを行うことができます.
gSOAPのインストール、導入については、ここでは紹介しませんが、ネット上には対応する指導方法がたくさんあります.
ドッキングを行う前に,まずサービス側がsoap 1を用いることを明確にする.1それともsoap 1.2,通常soap 1.2 soap 1と互換性がある.1,逆にだめです.
gSOAPツールパッケージには、2つのファイルwsdl 2 hとsoapcpp 2があり、この2つのツールファイルはwsdlファイルに基づいて一連のコードを逆コンパイルするために使用され、コードにはサービスのインタフェース、およびインタフェースに対応する各フィールドが含まれており、必要に応じてcまたはc++のコードを生成することができ、自分のコードでは、サービス側に転送する必要があるフィールドを組み立てた後、インタフェースを呼び出してデータの転送を行います.
逆コンパイルコード手順:
1.wsdl 2 hツールを使用して、wsdlファイルに基づいてc/c++構文構造のヘッダファイルを生成する
Wsdl 2 h–s–oヘッダファイル名wsdlファイル名
これによりヘッダーファイルが得られます.head.hこのステップの目的:WSDLファイルを実現する.hファイルのデータマッピング.
2.gSoapのプリコンパイラsoapcpp 2を使用します.
前のステップで得られたヘッダファイルに基づいて、ルートファイル(soapStub.h)とクライアントコードフレームワークを生成する.
/usr/local/gSOAP/bin/soapcpp2-i -x -C -L head.h
このステップはいくつか得られます.nsmap、.h和.cppファイル、例えば:calc.nsmap、soapC.cpp、soapH.h、soapStub.h、soapcalcProxy.cpp、soapcalcProxy.h
このステップの目的:対応する下位通信コードを生成する.
注意1:wsdl 2 hの使い方(WSDL/schema解析とコードジェネレータ)wsdl 2 h[opt]ヘッダファイル名WSDLファイル名またはURL
wsdl 2 h共通オプション
-oファイル名、出力ヘッダファイルを指定
-n名空間接頭辞がデフォルトのnsに代わる
-c純粋なCコードを生成します.そうでなければC++コードです.
-s STLコードは使用しない
-tファイル名、type mapファイルを指定し、デフォルトはtypemap.dat
-e enumメンバーに名前空間接頭辞を付けることを禁止
type mapファイルは、SOAP/XMLのタイプとC/C++の間の変換ルールを指定します.
sを使わないとSTL付きヘッダファイルが生成されるので,後のコンパイルではSTLのヘッダを加える必要がある.
stlvector.h、gsoap/import/ディレクトリの下にあります.
注意2:soapcpp 2の使い方(コンパイルとコードジェネレータ)
soapcpp 2[opt]ヘッダファイル名
soapcpp 2共通オプション
-Cクライアントコードのみ生成
-Sサーバ側コードのみ生成
-L soapClientLibを生成するなcとsoapServer Lib.cファイル
-c純粋なCコードを生成します.そうでない場合はC++コード(ヘッダファイルに関連)です.
-I importパスの指定(前述参照)
-x XMLサンプルファイルを生成しない
-iは、クライアントがxxxxxProxyであるC++パッケージ(エージェント)を生成する.h(.cpp)、サーバ側はxxxxサービスである.h(.cpp).
この例では、soapcpp 2-i-x-C-L calc.hを用いる
注意3:gSoapツールwsdl 2とsoapcppで生成されたファイルの簡単な分析
(1)wsdl 2が生成するC/C++シンタックス構造を有するヘッダファイルは、XMLシンタックス構造のWSDLファイルをC/C++シンタックス構造にマッピングする役割を果たす.hファイル;次のステップの準備をします.
(2)soapcpp(パラメータ:-i-x-C-Lを用いる)により生成するファイルは全部で6ファイル:PlayerBeanPortBinding.nsmap、soapC.cpp、soapH.h、soapPlayerBeanPortBindingProxy.cpp、soapPlayerBeanPortBindingProxy.h、soapStub.h.
a. PlayerBeanPortBinding.nsmapファイル
このファイルの役割:An XML-to-C/C++namespace mapping table、すなわちWSDLファイルと生成されたクライアントコードフレームワークの名前空間のマッピングテーブル.
b. soapStub.h
このファイルはwsdl 2によって直接生成されたヘッダファイルから変換され、WSDLに記述された各サービスおよびデータ構造を詳細に定義する.
これはsoapのルートファイルであり、wsdl 2によって生成されたヘッダファイルに対応するリモートコールモデル(RPC)を定義している.
c. soapPlayerBeanPortBindingProxy.そしてsoapPlayerBeanPortBindingProxy.cpp
この2つのファイルは、最下位通信をカプセル化し、ユーザが使用できるすべてのサービス(WSDLによって記述される)を示す簡単なインタフェースを外部に提供するクライアントコードの単純なカプセル化である.
d. soapH.hとsoapC.cpp
この2つのファイルはsoapのシーケンスと逆シーケンス化コードです.
注4:文字コードの設定
gSoapを用いてWeb Serviceクライアントとサーバ側のプログラムを記述する場合は,その符号化方式を設定する必要がある.インタフェース:soap_set_modeはマクロです
#define soap_set_mode(soap, n) ((soap)->imode |= (n),(soap)->omode |= (n))
UTF 8に設定する場合
このように呼び出すことができます:soap_set_mode(&soap,SOAP_C_UTFSTRING);
詳細は、マクロが存在するファイル:stdsoap 2を参照してください.h
例1:c呼び出しgSOAPによるwebservice通信
上記の方法で生成されたインタフェース関数を逆コンパイルすると、次のようになります.
インタフェース関数のコードを呼び出します.
例2:c++呼び出しgSOAPによるwebservice通信
コンパイルによって生成されたgSOAPインタフェース関数は次のとおりです.
ここで、インタフェース関数InViolationはクラスVcpServiceSoap 12 Proxyにカプセル化されているので、インタフェース関数を呼び出すには、まずVcpServiceSoap 12 Proxyクラスを初期化する必要がある
インタフェースの関数を呼び出します.
一般的に、wsdlファイル、アクセスurlアドレス、対応するフィールド定義ドキュメントが提供されるwebserviceサービス側は、gSOAPを使用してwebserviceドッキングを行うことができます.
gSOAPのインストール、導入については、ここでは紹介しませんが、ネット上には対応する指導方法がたくさんあります.
ドッキングを行う前に,まずサービス側がsoap 1を用いることを明確にする.1それともsoap 1.2,通常soap 1.2 soap 1と互換性がある.1,逆にだめです.
gSOAPツールパッケージには、2つのファイルwsdl 2 hとsoapcpp 2があり、この2つのツールファイルはwsdlファイルに基づいて一連のコードを逆コンパイルするために使用され、コードにはサービスのインタフェース、およびインタフェースに対応する各フィールドが含まれており、必要に応じてcまたはc++のコードを生成することができ、自分のコードでは、サービス側に転送する必要があるフィールドを組み立てた後、インタフェースを呼び出してデータの転送を行います.
逆コンパイルコード手順:
1.wsdl 2 hツールを使用して、wsdlファイルに基づいてc/c++構文構造のヘッダファイルを生成する
Wsdl 2 h–s–oヘッダファイル名wsdlファイル名
これによりヘッダーファイルが得られます.head.hこのステップの目的:WSDLファイルを実現する.hファイルのデータマッピング.
2.gSoapのプリコンパイラsoapcpp 2を使用します.
前のステップで得られたヘッダファイルに基づいて、ルートファイル(soapStub.h)とクライアントコードフレームワークを生成する.
/usr/local/gSOAP/bin/soapcpp2-i -x -C -L head.h
このステップはいくつか得られます.nsmap、.h和.cppファイル、例えば:calc.nsmap、soapC.cpp、soapH.h、soapStub.h、soapcalcProxy.cpp、soapcalcProxy.h
このステップの目的:対応する下位通信コードを生成する.
注意1:wsdl 2 hの使い方(WSDL/schema解析とコードジェネレータ)wsdl 2 h[opt]ヘッダファイル名WSDLファイル名またはURL
wsdl 2 h共通オプション
-oファイル名、出力ヘッダファイルを指定
-n名空間接頭辞がデフォルトのnsに代わる
-c純粋なCコードを生成します.そうでなければC++コードです.
-s STLコードは使用しない
-tファイル名、type mapファイルを指定し、デフォルトはtypemap.dat
-e enumメンバーに名前空間接頭辞を付けることを禁止
type mapファイルは、SOAP/XMLのタイプとC/C++の間の変換ルールを指定します.
sを使わないとSTL付きヘッダファイルが生成されるので,後のコンパイルではSTLのヘッダを加える必要がある.
stlvector.h、gsoap/import/ディレクトリの下にあります.
注意2:soapcpp 2の使い方(コンパイルとコードジェネレータ)
soapcpp 2[opt]ヘッダファイル名
soapcpp 2共通オプション
-Cクライアントコードのみ生成
-Sサーバ側コードのみ生成
-L soapClientLibを生成するなcとsoapServer Lib.cファイル
-c純粋なCコードを生成します.そうでない場合はC++コード(ヘッダファイルに関連)です.
-I importパスの指定(前述参照)
-x XMLサンプルファイルを生成しない
-iは、クライアントがxxxxxProxyであるC++パッケージ(エージェント)を生成する.h(.cpp)、サーバ側はxxxxサービスである.h(.cpp).
この例では、soapcpp 2-i-x-C-L calc.hを用いる
注意3:gSoapツールwsdl 2とsoapcppで生成されたファイルの簡単な分析
(1)wsdl 2が生成するC/C++シンタックス構造を有するヘッダファイルは、XMLシンタックス構造のWSDLファイルをC/C++シンタックス構造にマッピングする役割を果たす.hファイル;次のステップの準備をします.
(2)soapcpp(パラメータ:-i-x-C-Lを用いる)により生成するファイルは全部で6ファイル:PlayerBeanPortBinding.nsmap、soapC.cpp、soapH.h、soapPlayerBeanPortBindingProxy.cpp、soapPlayerBeanPortBindingProxy.h、soapStub.h.
a. PlayerBeanPortBinding.nsmapファイル
このファイルの役割:An XML-to-C/C++namespace mapping table、すなわちWSDLファイルと生成されたクライアントコードフレームワークの名前空間のマッピングテーブル.
b. soapStub.h
このファイルはwsdl 2によって直接生成されたヘッダファイルから変換され、WSDLに記述された各サービスおよびデータ構造を詳細に定義する.
これはsoapのルートファイルであり、wsdl 2によって生成されたヘッダファイルに対応するリモートコールモデル(RPC)を定義している.
c. soapPlayerBeanPortBindingProxy.そしてsoapPlayerBeanPortBindingProxy.cpp
この2つのファイルは、最下位通信をカプセル化し、ユーザが使用できるすべてのサービス(WSDLによって記述される)を示す簡単なインタフェースを外部に提供するクライアントコードの単純なカプセル化である.
d. soapH.hとsoapC.cpp
この2つのファイルはsoapのシーケンスと逆シーケンス化コードです.
注4:文字コードの設定
gSoapを用いてWeb Serviceクライアントとサーバ側のプログラムを記述する場合は,その符号化方式を設定する必要がある.インタフェース:soap_set_modeはマクロです
#define soap_set_mode(soap, n) ((soap)->imode |= (n),(soap)->omode |= (n))
UTF 8に設定する場合
このように呼び出すことができます:soap_set_mode(&soap,SOAP_C_UTFSTRING);
詳細は、マクロが存在するファイル:stdsoap 2を参照してください.h
例1:c呼び出しgSOAPによるwebservice通信
上記の方法で生成されたインタフェース関数を逆コンパイルすると、次のようになります.
SOAP_FMAC5 int SOAP_FMAC6 soap_call___ns4__InPeccancyInfo(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _ns2__InPeccancyInfo *ns2__InPeccancyInfo, struct _ns2__InPeccancyInfoResponse *ns2__InPeccancyInfoResponse)
{ struct __ns4__InPeccancyInfo soap_tmp___ns4__InPeccancyInfo;
if (!soap_endpoint)
soap_endpoint = "http://localhost:13059/Ehl.Atms.Tgs.WebService/VcpService.asmx";
if (!soap_action)
soap_action = "http://tempuri.org/InPeccancyInfo";
soap->encodingStyle = NULL;
soap_tmp___ns4__InPeccancyInfo.ns2__InPeccancyInfo = ns2__InPeccancyInfo;
soap_begin(soap);
soap_serializeheader(soap);
soap_serialize___ns4__InPeccancyInfo(soap, &soap_tmp___ns4__InPeccancyInfo);
if (soap_begin_count(soap))
return soap->error;
if (soap->mode & SOAP_IO_LENGTH)
{ if (soap_envelope_begin_out(soap)
|| soap_putheader(soap)
|| soap_body_begin_out(soap)
|| soap_put___ns4__InPeccancyInfo(soap, &soap_tmp___ns4__InPeccancyInfo, "-ns4:InPeccancyInfo", NULL)
|| soap_body_end_out(soap)
|| soap_envelope_end_out(soap))
return soap->error;
}
if (soap_end_count(soap))
return soap->error;
if (soap_connect(soap, soap_endpoint, soap_action)
|| soap_envelope_begin_out(soap)
|| soap_putheader(soap)
|| soap_body_begin_out(soap)
|| soap_put___ns4__InPeccancyInfo(soap, &soap_tmp___ns4__InPeccancyInfo, "-ns4:InPeccancyInfo", NULL)
|| soap_body_end_out(soap)
|| soap_envelope_end_out(soap)
|| soap_end_send(soap))
return soap_closesock(soap);
if (!ns2__InPeccancyInfoResponse)
return soap_closesock(soap);
soap_default__ns2__InPeccancyInfoResponse(soap, ns2__InPeccancyInfoResponse);
if (soap_begin_recv(soap)
|| soap_envelope_begin_in(soap)
|| soap_recv_header(soap)
|| soap_body_begin_in(soap))
return soap_closesock(soap);
soap_get__ns2__InPeccancyInfoResponse(soap, ns2__InPeccancyInfoResponse, "ns2:InPeccancyInfoResponse", "");
if (soap->error)
return soap_recv_fault(soap, 0);
if (soap_body_end_in(soap)
|| soap_envelope_end_in(soap)
|| soap_end_recv(soap))
return soap_closesock(soap);
return soap_closesock(soap);
}
インタフェース関数のコードを呼び出します.
#include
struct soap m_SoapClient
int main()
{
int ret = -1;
memset(&m_SoapClient, 0, sizeof(struct soap));
soap_init(&m_SoapClient);
soap_set_mode(&m_SoapClient, SOAP_C_UTFSTRING);
struct soap *pSoapTemp = NULL;
pSoapTemp = &m_SoapClient;
struct _ns2__InPeccancyInfo ns2__InPeccancyInfo;
struct _ns2__InPeccancyInfoResponse ns2__InPeccancyInfoResponse;
memset(&ns2__InPeccancyInfo,0,sizeof(struct _ns2__InPeccancyInfo));
memset(&ns2__InPeccancyInfoResponse,0,sizeof(struct _ns2__InPeccancyInfoResponse));
ret = soap_call___ns4__InPeccancyInfo(pSoapTemp, (const char*)urlPeccancy, NULL, &ns2__InPeccancyInfo, &ns2__InPeccancyInfoResponse);
if (SOAP_OK != ret)
{
printf("call soap OK!
");
}
else
{
printf("call soap failed!
");
}
soap_destroy(pSoapTemp);
soap_end(pSoapTemp);
soap_done(pSoapTemp);
return ret;
}
例2:c++呼び出しgSOAPによるwebservice通信
コンパイルによって生成されたgSOAPインタフェース関数は次のとおりです.
class SOAP_CMAC VcpServiceSoap12Proxy : public soap
{ public:
/// Endpoint URL of service 'VcpServiceSoap12Proxy' (change as needed)
const char *soap_endpoint;
/// Constructor
VcpServiceSoap12Proxy();
/// Construct from another engine state
VcpServiceSoap12Proxy(const struct soap&);
/// Constructor with endpoint URL
VcpServiceSoap12Proxy(const char *url);
/// Constructor with engine input+output mode control
VcpServiceSoap12Proxy(soap_mode iomode);
/// Constructor with URL and input+output mode control
VcpServiceSoap12Proxy(const char *url, soap_mode iomode);
/// Constructor with engine input and output mode control
VcpServiceSoap12Proxy(soap_mode imode, soap_mode omode);
/// Destructor frees deserialized data
virtual ~VcpServiceSoap12Proxy();
/// Initializer used by constructors
virtual void VcpServiceSoap12Proxy_init(soap_mode imode, soap_mode omode);
/// Delete all deserialized data (uses soap_destroy and soap_end)
virtual void destroy();
/// Delete all deserialized data and reset to default
virtual void reset();
/// Disables and removes SOAP Header from message
virtual void soap_noheader();
/// Get SOAP Header structure (NULL when absent)
virtual const SOAP_ENV__Header *soap_header();
/// Get SOAP Fault structure (NULL when absent)
virtual const SOAP_ENV__Fault *soap_fault();
/// Get SOAP Fault string (NULL when absent)
virtual const char *soap_fault_string();
/// Get SOAP Fault detail as string (NULL when absent)
virtual const char *soap_fault_detail();
/// Close connection (normally automatic, except for send_X ops)
virtual int soap_close_socket();
/// Force close connection (can kill a thread blocked on IO)
virtual int soap_force_close_socket();
/// Print fault
virtual void soap_print_fault(FILE*);
#ifndef WITH_LEAN
/// Print fault to stream
#ifndef WITH_COMPAT
virtual void soap_stream_fault(std::ostream&);
#endif
/// Put fault into buffer
virtual char *soap_sprint_fault(char *buf, size_t len);
#endif
/// Web service operation 'InViolation' (returns error code or SOAP_OK)
virtual int InViolation(_ns2__InViolation *ns2__InViolation, _ns2__InViolationResponse *ns2__InViolationResponse) { return InViolation(NULL, NULL, ns2__InViolation, ns2__InViolationResponse); }
virtual int InViolation(const char *endpoint, const char *soap_action, _ns2__InViolation *ns2__InViolation, _ns2__InViolationResponse *ns2__InViolationResponse);
};
int VcpServiceSoap12Proxy::InViolation(const char *endpoint, const char *soap_action, _ns2__InViolation *ns2__InViolation, _ns2__InViolationResponse *ns2__InViolationResponse)
{ struct soap *soap = this;
struct __ns4__InViolation soap_tmp___ns4__InViolation;
if (endpoint)
soap_endpoint = endpoint;
if (!soap_endpoint)
soap_endpoint = "http://localhost/Ehl.Atms.Tgs.WebService/VcpService.asmx";
if (!soap_action)
soap_action = "http://tempuri.org/InViolation";
soap->encodingStyle = NULL;
soap_tmp___ns4__InViolation.ns2__InViolation = ns2__InViolation;
soap_begin(soap);
soap_serializeheader(soap);
soap_serialize___ns4__InViolation(soap, &soap_tmp___ns4__InViolation);
if (soap_begin_count(soap))
return soap->error;
if (soap->mode & SOAP_IO_LENGTH)
{ if (soap_envelope_begin_out(soap)
|| soap_putheader(soap)
|| soap_body_begin_out(soap)
|| soap_put___ns4__InViolation(soap, &soap_tmp___ns4__InViolation, "-ns4:InViolation", NULL)
|| soap_body_end_out(soap)
|| soap_envelope_end_out(soap))
return soap->error;
}
if (soap_end_count(soap))
return soap->error;
if (soap_connect(soap, soap_endpoint, soap_action)
|| soap_envelope_begin_out(soap)
|| soap_putheader(soap)
|| soap_body_begin_out(soap)
|| soap_put___ns4__InViolation(soap, &soap_tmp___ns4__InViolation, "-ns4:InViolation", NULL)
|| soap_body_end_out(soap)
|| soap_envelope_end_out(soap)
|| soap_end_send(soap))
return soap_closesock(soap);
if (!ns2__InViolationResponse)
return soap_closesock(soap);
ns2__InViolationResponse->soap_default(soap);
if (soap_begin_recv(soap)
|| soap_envelope_begin_in(soap)
|| soap_recv_header(soap)
|| soap_body_begin_in(soap))
return soap_closesock(soap);
ns2__InViolationResponse->soap_get(soap, "ns2:InViolationResponse", "");
if (soap->error)
return soap_recv_fault(soap, 0);
if (soap_body_end_in(soap)
|| soap_envelope_end_in(soap)
|| soap_end_recv(soap))
return soap_closesock(soap);
return soap_closesock(soap);
}
ここで、インタフェース関数InViolationはクラスVcpServiceSoap 12 Proxyにカプセル化されているので、インタフェース関数を呼び出すには、まずVcpServiceSoap 12 Proxyクラスを初期化する必要がある
インタフェースの関数を呼び出します.
#include "soapVcpServiceSoap12Proxy.h"
int main()
{
VcpServiceSoap12Proxy *pSoapVcpServiceProxy;
_ns2__InViolation peccancyCarInfo;
_ns2__InViolationResponse peccancyCarInfoRes;
pSoapVcpServiceProxy = new VcpServiceSoap12Proxy(urlPeccancy, SOAP_C_UTFSTRING);
ret = pSoapVcpServiceProxy->InViolation(urlPeccancy, NULL, &peccancyCarInfo, &peccancyCarInfoRes);
if(SOAP_OK != ret)
{
delete pSoapVcpServiceProxy;
return ERROR;
}
delete pSoapVcpServiceProxy;
return ret;
}