導航:首頁 > 編程語言 > java調用gsoap

java調用gsoap

發布時間:2022-04-25 06:22:45

❶ 怎麼使用gsoap

接下來我結合自己的實踐與理解,講講VC用gsoap下編寫webService和客戶端程序,有不對的地方還請大家指正,謝謝。
我以網上出現的實現一個簡單的加法函數為例,講講我在操作過程中遇到的問題。


伺服器端
1.首先編寫 add.h文件:

1//gsoap ns service name: add
2//gsoap ns service namespace: http://localhost/add.wsdl
3//gsoap ns service location: http://localhost
4//gsoap ns service executable: add.cgi
5//gsoap ns service encoding: encoded
6//gsoap ns schema namespace: urn:add
7
8int ns__add( int num1, int num2, int* sum );
9

2.用gsoap/bin目錄下的soapcpp2.exe程序,生成一些文件。可以把soapcpp2.exe拷貝到一add.h目錄下,用cmd執行soapcpp2.exe
add.h就可以,在這個目錄下會自動生成許多將來有用的文件,如add.namap,soapH.h,soapC.cpp,soapClient.cpp,soapServer.cpp等文件。soapcpp2.exe可以帶參數執行,具體執行soapcpp2.exe
-h查看。

3.新建一個win32控制台工程,加入wsock32.lib庫,將剛才生成的那些文件添加到工程中。然後編寫webserver.cpp主程序:

#include "add.h"
#include "add.nsmap"

int main(int argc, char* argv[])
{

int m, s; /**//* master and slave sockets */
struct soap add_soap;
soap_init(&add_soap);
//soap_set_namespaces(&add_soap, add_namespaces);

if (argc < 2)
{
printf("usage: %s <server_port> \n", argv[0]);
exit(1);
}
else
{
m = soap_bind(&add_soap, NULL, atoi(argv[1]), 100);
if (m < 0)
{
soap_print_fault(&add_soap, stderr);
exit(-1);
}

fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
for ( ; ; )
{
s = soap_accept(&add_soap);
if (s < 0)
{
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);

soap_serve(&add_soap);//該句說明該server的服務
soap_end(&add_soap);
}
}
return 0;
}
//server端的實現函數與add.h中聲明的函數相同,但是多了一個當前的soap連接的參數
int ns__add(struct soap *add_soap, int num1, int num2, int *sum)
{
*sum = num1 + num2;
return 0;
}

4.
編譯這個程序,會提示錯誤,將gsoap_win32目錄下stdsoap2.cpp,stdsoap2.h文件加入工程,重新編譯如果還有錯誤,可能是你將add.h生成的文件添加入工程出錯的原因。實際上在編寫server程序時,無須帶Client的那些文件,還有帶Lib的文件也無須添加到工程中。再重新編譯應該就沒有問題了,啟動4567埠,在ie中輸入localhost:4567,如果顯示xml頁面,說明程序已經啟動。


對應的客戶端
1。客戶端程序代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include "soapH.h"
#include "add.nsmap"

int add(const char* server, int num1, int num2, int *sum);

int main(int argc, char **argv)
{
int result = -1;
char* server="http://localhost:4567";
int num1 = 0;
int num2 = 0;
int sum = 0;
if( argc < 3 )
{
printf("usage: %s num1 num2 \n", argv[0]);
exit(0);
}

num1 = atoi(argv[1]);
num2 = atoi(argv[2]);

result = add(server, num1, num2, &sum);
if (result != 0)
{
printf("soap err,errcode = %d\n", result);
}
else
{
printf("%d+%d=%d\n", num1, num2, sum );
}
return 0;
}

int add( const char* server, int num1, int num2, int *sum )
{
struct soap add_soap;
int result = 0;
soap_init(&add_soap);
// soap_set_namespaces(&add_soap, add_namespaces);

//該函數是客戶端調用的主要函數,後面幾個參數和add.h中聲明的一樣,前面多了3個參數,函數名是介面函數名ns__add前面加上soap_call_
soap_call_ns__add( &add_soap, server, "", num1, num2, sum );
if(add_soap.error)
{
printf("soap error:%d,%s,%s\n", add_soap.error, *soap_faultcode(&add_soap), *soap_faultstring(&add_soap) );
result = add_soap.error;
}
soap_end(&add_soap);
soap_done(&add_soap);
return result;
}

2.客戶端程序既可以新建一個新的win32控制台程序,將剛才生成的nsmap,soapH.h,soapClient.h等文件加入工程,編譯既可。我是直接在原先工程中加入一客戶端代碼,將webserver.cpp文件移除,並且將soapServer.cpp等server端需要的文件移除,將soapClient.cpp等client端需要的cpp添加到工程,編譯既可。
3.啟動server程序,F5客戶端程序,經測試正常。


遇到的問題
1.server端可以編譯成CGI方式執行,而並不是綁定到某個埠,這種方式我沒有實踐。

if (argc < 2) // no args: assume this is a CGI application
{
soap_serve(&soap); // serve request, one thread, CGI style
soap_destroy(&soap); // dealloc C++ data
soap_end(&soap); // dealloc data and clean up
}
2.在編譯伺服器及客戶端程序時一開始對add.h生成的文件添加到工程,經常出現問題,需要自己不調試。特別是鏈接時段,server/client要與其生成的文件相對應,server調用生成的soapserver.cpp,client調用生成的soapclient.cpp文件。
3.多線程方式,在windows下建議用pthread_win32庫,這里給出多線程下的例子。

一 gSOAP需要的頭文件:

//gsoap ns service name: calc
//gsoap ns service style: rpc
//gsoap ns service encoding: encoded
//gsoap ns service namespace: http://127.0.0.1:8089/calc.wsdl
//gsoap ns service location: http://127.0.0.1:8089/cal
//gsoap ns schema namespace: urn:calc
int ns__add(double a, double b, double *result);
int ns__sub(double a, double b, double *result);
int ns__mul(double a, double b, double *result);
int ns__div(double a, double b, double *result);
int ns__pow(double a, double b, double *result);

二 多線程伺服器關鍵代碼

#include
#include "calc.nsmap"
#include "soapH.h"

/**//////////////////////////////////////////////////////////////////////////
///宏與全局變數的定義
#define BACKLOG (100)
#define MAX_THR (10)
#define MAX_QUEUE (1000)

pthread_mutex_t queue_cs; //隊列鎖
pthread_cond_t queue_cv; //條件變數
SOAP_SOCKET queue[MAX_QUEUE]; //數組隊列
int head =0, tail =0; //隊列頭隊列尾初始化
/**///////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
void * process_queue(void *); //線程入口函數
int enqueue(SOAP_SOCKET); //入隊列函數
SOAP_SOCKET dequeue(void); //出隊列函數

/**///////////////////////////////////////////////////////////////////////////
//線程入口函數
void * process_queue(void * soap)
{
struct soap * tsoap = (struct soap *)soap;
for(;;)
{
tsoap->socket = dequeue();
if (!soap_valid_socket(tsoap->socket))
{
break;
}
soap_serve(tsoap);
soap_destroy(tsoap);
soap_end(tsoap);
}
return NULL;
}

//入隊列操作
int enqueue(SOAP_SOCKET sock)
{
int status = SOAP_OK;
int next;
pthread_mutex_lock(&queue_cs);
next = tail +1;
if (next >= MAX_QUEUE)
next = 0;
if (next == head)
status = SOAP_EOM;
else
{
queue[tail] =sock;
tail = next;
}
pthread_cond_signal(&queue_cv);
pthread_mutex_unlock(&queue_cs);
return status;
}

//出隊列操作
SOAP_SOCKET dequeue()
{
SOAP_SOCKET sock;
pthread_mutex_lock(&queue_cs);
while (head == tail )
{
pthread_cond_wait(&queue_cv,&queue_cs);
}
sock = queue[head++];
if (head >= MAX_QUEUE)
{
head =0;
}
pthread_mutex_unlock(&queue_cs);
return sock;
}

/**///////////////////////////具體服務方法////////////////////////////////////////
//加法的實現
int ns__add(struct soap *soap, double a, double b, double *result)
{
*result = a + b;
return SOAP_OK;
}
//減法的實現
int ns__sub(struct soap *soap, double a, double b, double *result)
{
*result = a - b;
return SOAP_OK;
}
//乘法的實現
int ns__mul(struct soap *soap, double a, double b, double *result)
{
*result = a * b;
return SOAP_OK;
}
//除法的實現
int ns__div(struct soap *soap, double a, double b, double *result)
{
if (b)
*result = a / b;
else
{
char *s = (char*)soap_malloc(soap, 1024);
sprintf(s, "Can't">http://tempuri.org/">Can't divide %f by %f", a, b);
return soap_sender_fault(soap, "Division by zero", s);
}
return SOAP_OK;
}
//乘方的實現
int ns__pow(struct soap *soap, double a, double b, double *result)
{
*result = pow(a, b);
if (soap_errno == EDOM) /**//* soap_errno 和errorno類似, 但是和widnows兼容 */
{
char *s = (char*)soap_malloc(soap, 1024);
sprintf(s, "Can't take the power of %f to %f", a, b);
sprintf(s, "Can't">http://tempuri.org/">Can't take power of %f to %f", a, b);
return soap_sender_fault(soap, "Power function domain error", s);
}
return SOAP_OK;
}

/**///////////////////////////////////////////////////////////////////////////////////////////////////////
//主函數
int main(int argc,char ** argv)
{
struct soap ServerSoap;
//初始話運行時環境
soap_init(&ServerSoap);
//如果沒有參數,當作CGI程序處理
if (argc <2)
{
//CGI 風格服務請求,單線程
soap_serve(&ServerSoap);
//清除序列化的類的實例
soap_destroy(&ServerSoap);
//清除序列化的數據
soap_end(&ServerSoap);
}else
{
struct soap * soap_thr[MAX_THR];
pthread_t tid[MAX_THR];
int i,port = atoi(argv[1]);
SOAP_SOCKET m,s;
//鎖和條件變數初始化
pthread_mutex_init(&queue_cs,NULL);
pthread_cond_init(&queue_cv,NULL);
//綁定服務埠
m = soap_bind(&ServerSoap,NULL,port,BACKLOG);
//循環直至服務套接字合法
while (!soap_valid_socket(m))
{
fprintf(stderr,"Bind port error! ");
m = soap_bind(&ServerSoap,NULL,port,BACKLOG);
}
fprintf(stderr,"socket connection successful %d ",m);

//生成服務線程
for(i = 0; i <MAX_THR; i++)

{
soap_thr[i] = soap_(&ServerSoap);
fprintf(stderr,"Starting thread %d ",i);
pthread_create(&tid[i],NULL,(void*(*)(void*))process_queue,(void*)soap_thr[i]);
}

for(;;)
{
//接受客戶端的連接
s = soap_accept(&ServerSoap);
if (!soap_valid_socket(s))
{
if (ServerSoap.errnum)
{
soap_print_fault(&ServerSoap,stderr);
continue;
}else
{
fprintf(stderr,"Server timed out ");
break;
}
}
//客戶端的IP地址
fprintf(stderr,"Accepted connection from IP= %d.%d.%d.%d socket = %d ",
((ServerSoap.ip)>>24)&&0xFF,((ServerSoap.ip)>>16)&0xFF,((ServerSoap.ip)>>8)&0xFF,(ServerSoap.ip)&0xFF,(ServerSoap.socket));
//請求的套接字進入隊列,如果隊列已滿則循環等待
while(enqueue(s) == SOAP_EOM)
Sleep(1000);
}
//服務結束後的清理工作
for(i = 0; i < MAX_THR; i++)
{
while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
{
Sleep(1000);
}
}
for(i=0; i< MAX_THR; i++)
{
fprintf(stderr,"Waiting for thread %d to terminate ..",i);
pthread_join(tid[i],NULL);
fprintf(stderr,"terminated ");
soap_done(soap_thr[i]);
free(soap_thr[i]);
}
pthread_mutex_destroy(&queue_cs);
pthread_cond_destroy(&queue_cv);
}
//分離運行時的環境
soap_done(&ServerSoap);
return 0;
}

❷ 調用ws(webservice)介面時可以不用gsoap么還有什麼實現方式

1、C++可以實現webservice,這是毋庸置疑的.axis2本質是運行在tomcat下的一個servlet,分java版本,和C語言版本.官方網站為:,首頁上寫著:
The well known Apache Axis, and the the second generation of it, the Apache Axis2, are two Web Service containers that helps users to create, deploy, and run Web Services.Axis2 is avaialble in both Java as well as C, languages and details about each version can be found below. 大概意思就是這東西分java版本和C版本,可以方便用戶創建,部署,運行web service.而C++完全是兼容C的.
2、需要伺服器,要實現某個服務吧,至於怎樣為其他平台服務,主要是監聽埠實現解析http協議.js不需要拼串成XML,伺服器才要拼串,JS是運行在客戶端的,客戶端也不是通過SOAP與服務端進行通訊的,而是根據需要調用的服務的WSDL,提供對應參數,客戶端與服務端的通訊是用http協議的,而通訊方式根據是GET還是POST把相關參數放到HTTP頭或者體中.而web service之間的通訊才可能用得到SOAP.
3、PHP調用web service是非常簡單的,貌似有個函數通過SOAP調用.C++編寫的web service肯定有WSDL,可以根據WSDL描述的埠參數,來調用.
數值和的平均值。 特別提醒:如果引

❸ 如何在C/C++中調用Java

Java端可以做成網路服務,方法就很多了,可以是RESTful形式、基於SOAP的WebService、或者用Netty等。C/C++端可以通過開源庫libcurl調用RESTful形式的介面、可以通過gSoap調用基於SOAP的WebService介面。

❹ java調用webservice怎麼添加 SoapHeader 做驗證

如果你是用axis生成的代碼的話 去用CUX_0_WS_SERVER_PRG_BindingStub.java 這個類調用服務。
CUX_0_WS_SERVER_PRG_Service service=new CUX_0_WS_SERVER_PRG_ServiceLocator();
CUX_0_WS_SERVER_PRG_BindingStub stub=(CUX_0_WS_SERVER_PRG_BindingStub)service.CUX_0_WS_SERVER_PRGSOAP();
stub.setUsername("aaaa"); //連接的用戶名
stub.setPassword("aaaa"); //連接的密碼
stub.setHeader( dddd); //dddd是一個SOAPHeader 具體看對方wsdl要求
stub.invokefmsws(so.in);

不知道對方要求怎麼驗證 是在header中添加用戶名和密碼 還是在連接時需提供用戶名密碼。
所以把添加header 和 使用用戶名 密碼連接 驗證都寫了。 找對方確認下用那種方式然後自己試一下。

❺ JAVA,不用TOMCAT等WEB伺服器如果實現SOAP服務

目前我做的服務端,都是用web project做的,所以必須跑在tomcat等容器上。你想用一個框架,用java project來實現服務端嗎?好像是不行——如果想實現客戶端,用java project倒是沒有問題的

❻ gSOAP基於 HTTP 的基本認證 (Basic Authentication)

od

❼ gsoap怎麼調用webservice 介面函數

1、下載soap

2、解壓到c:\gsoap-2.7

3、將c:\gsoap-2.7下的soapcpp2.exe,wsdl2h.exe,stdsoap2.h,stdsoap2.cpp拷貝到C:\wstest\client\gsoap2.7目錄下

4、在C:\wstest\client\gsoap2.7目錄下執行soapcpp2 -C -x test.h -I "C:/gsoap-2.7/gsoap/import"

5、在C:\wstest\client\gsoap2.7目錄下執行wsdl2h -I "C:/gsoap-2.7/gsoap/WS" -s
-o test.h http://192.168.81.191:5000/....../CWSCrm.asmx?wsdl

6、將C:\wstest\client\gsoap2.7目錄下文件拷貝到C:\wstest\client\test\目錄下

7、新建立qt5項目,test.pro文件:
QT += core gui
QT +=network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test
TEMPLATE = app
SOURCES += main.cpp\

mainwindow.cpp \

stdsoap2.cpp \

soapC.cpp \
soapClient.cpp
HEADERS += mainwindow.h \

stdsoap2.h \

soapH.h \

stdsoap2.h \

soapStub.h
FORMS += mainwindow.ui
LIBS += -L . -l ws2_32

mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHBoxLayout>
#include "CWSCrmSoap.nsmap"
#include "soapCWSCrmSoapProxy.h"
#include "soapH.h"

wsdl2h常用選項
-o 文件名,指定輸出頭文件
-n 名空間前綴 代替默認的ns
-c 產生純C代碼,否則是C++代碼
-s 不要使用STL代碼
-t 文件名,指定type map文件,默認為typemap.dat
-e 禁止為enum成員加上名空間前綴

soapcpp2常用選項
-C 僅生成客戶端代碼
-S 僅生成伺服器端代碼
-L 不要產生soapClientLib.c和soapServerLib.c文件
-c 產生純C代碼,否則是C++代碼(與頭文件有關)
-I 指定import路徑
-x 不要產生XML示例文件
-i 生成C++包裝,客戶端為xxxxProxy.h(.cpp),伺服器端為xxxxService.h(.cpp)。

❽ 我手上現在做一個指紋識別的二次開發,開發包中沒有Java的例子,遇到以下問題

想java調dll的話 只有2種方法,可能稍微絕對,反正我知道的 只有這2種,第一就是jna或者jni了 兩者原理一樣,只不過一個是封裝了而已,這個肯定能行,多看例子吧,第二種就是藉助webservice了,對外提供一個介面,這個介面就類似於地址,java訪問到地址自然就能得到一個json串,這個json串就是dll生成的,如果採用第二種方法建議你使用gsoap,能節省很多代碼量,但是前提你要對c++比較熟悉。就講這么多吧,jni跟webservice的例子好多的,一搜一把的。

❾ gsoap 調用webservice內存泄漏

gsoap調用webservice出現內存泄漏
程序運行起來後內存一直增長,出現了內存泄漏,經過各模塊的測試分析,將泄漏代碼出現在這一段。
/*webservice客戶端函數,上傳本地資料庫數據到遠程伺服器*/
int
sendtowebservice(char
**data_values,int
n_columns,sqlite3*
conn)
{
char
sql[200]="
";
char
*err_msg;
int
res;
struct
soap
*clientsoap
=
soap_new();
soap_cmac
_ns1__sendonemessage
sendmsg;
soap_cmac
_ns1__sendonemessageresponse
sendmsgresponse;
#if
1
soap_init(clientsoap);
sendmsg.grpid=atoi(data_values[0]);
sendmsg.ctime=atoi(data_values[1]);
sendmsg.allencount=atoi(data_values[2]);
sendmsg.alloutcount=atoi(data_values[3]);
printf("sendmsg.grpid=%d;sendmsg.ctime=%d;sendmsg.encount=%d;sendmsg.outcount=%d\n",sendmsg.grpid,sendmsg.ctime,sendmsg.allencount,sendmsg.alloutcount);
sprintf_s(buffer,sizeof(buffer),"sendmsg.grpid=%d;sendmsg.ctime=%d;sendmsg.encount=%d;sendmsg.outcount=%d",sendmsg.grpid,sendmsg.ctime,sendmsg.allencount,sendmsg.alloutcount);
writelog(buffer);
struct
soap_env__header
header;
clientsoap->header=&header;
string
strid("admin");
string
strpsw("123456");
soap_cmac
ns1__mysoapheader
mysoapheader;
mysoapheader.userid=&strid;
mysoapheader.userpw=&strpsw;
header.ns1__mysoapheader_=&mysoapheader;
clientsoap->header=&header;
if(soap_call___ns1__sendonemessage(clientsoap,
null,
null,
&sendmsg,
&sendmsgresponse)==soap_ok)
{
//printf("response=%d\n
",
sendmsgresponse.sendonemessageresult);
sprintf_s(buffer,sizeof(buffer),"sendmsgresponse.sendonemessageresult=%d",sendmsgresponse.sendonemessageresult);
writelog(buffer);
/*
-1
=驗證失敗,
-2=失敗,1=插入成功,2=更新成功;
插入成功,更新成功寫資料庫,將數據標為已發送。
失敗,返回-1,上傳數據線程釋放資源
*/
switch(sendmsgresponse.sendonemessageresult)
{
case
0:
soap_destroy(clientsoap);
soap_end(clientsoap);
soap_done(clientsoap);
return
-1;
break;
case
1:
writelog("上傳到伺服器,數據插入成功");
sprintf_s(sql,sizeof(sql),"update
grp
set
issend=%d
where
ctime=%d
and
gropid=%d",1,atoi(data_values[1]),atoi(data_values[0]));
res=sqlite3_exec(conn,
sql,
null,
0,
&err_msg);
if(res!=sqlite_ok)
{
fprintf(stderr,"操作失敗,錯誤代碼:%s",err_msg);
sprintf_s(buffer,sizeof(buffer),"操作失敗,錯誤代碼:%s",err_msg);
writelog(buffer);
}
else
{
printf("本地數據issend更新為1成功\n");
writelog("本地數據issend更新為1成功");
}
sqlite3_free(err_msg);
break;
case
2:
writelog("上傳到伺服器,數據更新成功");
sprintf_s(sql,sizeof(sql),"update
grp
set
issend=%d
where
ctime=%d
and
gropid=%d",1,atoi(data_values[1]),atoi(data_values[0]));
res=sqlite3_exec(conn,
sql,
null,
0,
&err_msg);
if(res!=sqlite_ok)
{
fprintf(stderr,"操作失敗,錯誤代碼:%s\n",err_msg);
sprintf_s(buffer,sizeof(buffer),"操作失敗,錯誤代碼:%s",err_msg);
writelog(buffer);
}
else
{
printf("本地數據issend更新為1成功\n");
writelog("本地數據issend更新為1成功");
}
sqlite3_free(err_msg);
break;
case
-1:
writelog("-1,連接伺服器驗證失敗");
soap_destroy(clientsoap);
soap_end(clientsoap);
soap_done(clientsoap);
return
-1;
break;
case
-2:
writelog("-2,失敗");
soap_destroy(clientsoap);
soap_end(clientsoap);
soap_done(clientsoap);

❿ fastcgi怎麼調用gsoap代碼

1、下載soap 2、解壓到c:\gsoap-2.7 3、將c:\gsoap-2.7下的soapcpp2.exe,wsdl2h.exe,stdsoap2.h,stdsoap2.cpp拷貝到C:\wstest\client\gsoap2.7目錄下 4、在C:\wstest\client\gsoap2.7目錄下執行soapcpp2 -C -x test.h -I "C:/gsoap-2.7/gsoap/i...

閱讀全文

與java調用gsoap相關的資料

熱點內容
解壓包如何轉音頻 瀏覽:447
機明自動編程軟體源碼 瀏覽:325
php埠號設置 瀏覽:540
phperegreplace 瀏覽:319
androidgridview翻頁 瀏覽:537
ssh協議編程 瀏覽:634
如何開我的世界電腦伺服器地址 瀏覽:861
玄關pdf 瀏覽:609
程序員學習論壇 瀏覽:940
程序員的毒雞湯怎麼做 瀏覽:548
安卓怎麼降級軟體到手機 瀏覽:281
雲與伺服器入門書籍推薦產品 瀏覽:636
delphi編程助手 瀏覽:761
電腦遇到伺服器問題怎麼辦 瀏覽:515
加工中心編程結束方法 瀏覽:296
了解什麼是web伺服器 瀏覽:139
面向對象的編程的基本特徵 瀏覽:718
php定時執行任務linux 瀏覽:787
php數組中刪除元素 瀏覽:725
螢石雲伺服器視頻 瀏覽:270