Linux 下使用Webservice gSOAP教程(二)

转自:https://blog.csdn.net/bytxl/article/details/11627249

生成wsdl文件步骤

头文件如下(注意空格问题)

// ws_interface.h

#ifndef  WS_INTERFACE_H
#define  WS_INTERFACE_H
// 注意:以下注释是必要的
//gsoap ns service name: ws_interface
//gsoap ns service style: rpc
//gsoap ns service namespace: https://127.0.0.1:4433/cgi-bin/ws_interface.wsdl
//gsoap ns service location: https://127.0.0.1:4433/cgi-bin
//gsoap ns service executable: ws_interface.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:ws_interface


typedef struct ns__AddGroupRequest
{
    char *validationCode;
    char *name;
    char *desc;
} ns__AddGroupRequest;

typedef struct ns__AddGroupResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__AddGroupResponse;

typedef struct ns__DelGroupRequest
{
    char *validationCode;
    char *name;
} ns__DelGroupRequest;

typedef struct ns__DelGroupResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__DelGroupResponse;

typedef struct ns__OpGroupRequest
{
    char *validationCode;
    char *name;
    int enable;     // 0 disable, 1 enable
} ns__OpGroupRequest;

typedef struct ns__OpGroupResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__OpGroupResponse;

typedef struct ns__ModifyGroupRequest
{
    char *validationCode;
    char *name;
    char *newname;
} ns__ModifyGroupRequest;

typedef struct ns__ModifyGroupResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__ModifyGroupResponse;

typedef struct ns__AddUserRequest
{
    char *validationCode;
    char *name;
    char *truename;
    char *passwd;
    char *groupname;            // user belong to group name
} ns__AddUserRequest;

typedef struct ns__AddUserResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__AddUserResponse;

typedef struct ns__DelUserRequest
{
    char *validationCode;
    char *name;
} ns__DelUserRequest;

typedef struct ns__DelUserResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__DelUserResponse;

typedef struct ns__OpUserRequest
{
    char *validationCode;
    char *name;
    int enable;     // 0 disable, 1 enable
} ns__OpUserRequest;

typedef struct ns__OpUserResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__OpUserResponse;

typedef struct ns__ModifyUserRequest
{
    char *validationCode;
    char *name;
    char *newname;
    char *truename;
    char *passwd;
    char *groupname;            // user belong to group name
} ns__ModifyUserRequest;

typedef struct ns__ModifyUserResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__ModifyUserResponse;

int ns__AddGroup(
ns__AddGroupRequest *AddGroup,
ns__AddGroupResponse *AddGroupResponse );

int ns__DelGroup(
ns__DelGroupRequest *DelGroupRequest,
ns__DelGroupResponse *DelGroupResponse );

int ns__OpGroup(
ns__OpGroupRequest *OpGroupRequest,
ns__OpGroupResponse *OpGroupResponse );

int ns__ModifyGroup(
ns__ModifyGroupRequest *ModifyGroupRequest,
ns__ModifyGroupResponse *ModifyGroupResponse );

int ns__AddUser(
ns__AddUserRequest *AddUserRequest,
ns__AddUserResponse *AddUserResponse );

int ns__DelUser(
ns__DelUserRequest *DelUserRequest,
ns__DelUserResponse *DelUserResponse );

int ns__OpUser(
ns__OpUserRequest *OpUserRequest,
ns__OpUserResponse *OpUserResponse );

int ns__ModifyUser(
ns__ModifyUserRequest *ModifyUserRequest,
ns__ModifyUserResponse *ModifyUserResponse );

#endif

运行如下命令生成wsdl与源文件:

mkdir ws_interface     //生成文件后保存的位置

soapcpp2 -Scd ./ws_interface ./ws_interface.h

关于类型的定义

不能因为某个结构一致,而使用typedef定义别名,这样在生成的wsdl中会有两个同样名字的参数,

而导致wsdl文件出现语法错误

例如,如下的头文件是错误的:

// ws_interface.h

#ifndef  WS_INTERFACE_H
#define  WS_INTERFACE_H

//gsoap ns service name: ws_interface
//gsoap ns service style: rpc
//gsoap ns service namespace: https://127.0.0.1:4433/cgi-bin/ws_interface.wsdl
//gsoap ns service location: https://127.0.0.1:4433/cgi-bin
//gsoap ns service executable: ws_interface.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:ws_interface

typedef struct ns__CommonResponse
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__CommonResponse;


typedef struct ns__AddGroupRequest
{
    char *validationCode;
    char *name;
    char *desc;
} ns__AddGroupRequest;

typedef struct ns__DelGroupRequest
{
    char *validationCode;
    char *name;
} ns__DelGroupRequest;

typedef struct ns__CommonResponse ns__AddGroupResponse;
int ns__AddGroup(
ns__AddGroupRequest *AddGroup,
ns__AddGroupResponse *AddGroupResponse );

typedef struct ns__CommonResponse ns__DelGroupResponse;
int ns__DelGroup(
ns__DelGroupRequest *DelGroupRequest,
ns__DelGroupResponse *DelGroupResponse );

#endif

关于gsoap生成的返回值

自定义头文件group.h

typedef struct ns__CommonResponse111111111
{
    int returnFlag;
    char *msg;              // message to descript the return_flag
} ns__CommonResponse2222222222;

typedef struct ns__AddGroupRequest
{
    char *validationCode;
    char *name;
    char *desc;
} ns__AddGroupRequest;

int ns__AddGroup(
ns__AddGroupRequest *AddGroupRequest,
ns__CommonResponse2222222222 *CommonResponse );

/

然后用如下命令生成.c文件:

soapcpp2 -S -c group.h

程序运行时,返回的数据被CommonResponse2222222222包裹:

<?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:ws_account"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<ns:CommonResponse2222222222>

<returnFlag>-460</returnFlag>

<msg>group name is empty</msg>

</ns:CommonResponse2222222222>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

注意:soapcpp2 -S -c group.h命令生成的样例res.xml中数据是被CommonResponse111111111包裹,与实际运行程序后生成的数据不符

 

具体应用测试代码:

C++:https://download.csdn.net/download/yuchunhai321/10681414

C :https://download.csdn.net/download/yuchunhai321/10708628

 

设置webservice传输中文为UTF8格式, soap_set_mode(proxy->soap,  SOAP_C_UTFSTRING);

 

C语言用gsoap传递结构型数组 ---转载,未认证

传递一个结构型数组。结构定义如下:

struct JobStatusDetail {
  int jobId;
  int status;
  char cpuTime[10];
  char wallTime[10];
}

步骤一、定义gsoap的.h文件

//gsoap ns service name:        JobService
//gsoap ns service style:       rpc
//gsoap ns service encoding:    encoded
//gsoap ns service namespace:   http://abc.com/Jobservice.wsdl
//gsoap ns service location:    http://abc.com/Jobservice.cgi

//gsoap ns schema namespace:    urn:JobService
typedef struct JobStatusDetail {
   int jobId;
  int status;
  char cpuTime[10];
  char wallTime[10];
} testType;

typedef testType *xsd__JobStatusDetailPointer;
  struct ns__JobStatusPointer {
  xsd__JobStatusDetailPointer  *__ptr;
  int __size;
};
int ns__StructArrayTest(char *cmd, struct ns__JobStatusPointer *structResult);

步骤二、实现服务器端的函数如下,整个gsoap服务器端程序结构可参见gsoap服务器与客户机程序的建立过程

int ns__StructArrayTest(struct soap *soap, char *cmd, struct ns__JobStatusPointer *structResult) {

  structResult->__size=2; //数组有两个element
  structResult->__ptr = malloc((structResult->__size+1)*sizeof(*structResult->__ptr));

  structResult->__ptr[0]=(testType *)malloc(sizeof(testType));
  (*structResult->__ptr[0]).jobId=1;  //搞了很久,终于明白(*structResult->__ptr[0])里一定存放结构具体内容
  (*structResult->__ptr[0]).status=1;
   strcpy((*structResult->__ptr[0]).cpuTime,"11:11:11");
   strcpy((*structResult->__ptr[0]).wallTime,"22:22:22");

   structResult->__ptr[1]=(testType *)malloc(sizeof(testType));
   (*structResult->__ptr[1]).jobId=2;
   (*structResult->__ptr[1]).status=2;
   strcpy((*structResult->__ptr[1]).cpuTime,"33:33:33");
   strcpy((*structResult->__ptr[1]).wallTime,"44:44:44");
  return SOAP_OK;
}

 

步骤三、实现客户端程序

#include "soapH.h"
#include "JobService.nsmap"
#include <string.h>
const char server[] = "http://**.**.**:nnnn";

static char Server[]="**.**.**";
int main(int argc, char **argv)
{
  struct soap soap;

  char buf[1024]="Tell me the job status!";
  struct ns__JobStatusPointer result;
  if (argc<1)
  {
    fprintf(stderr, "Usage: jobOptionfile \n");
    exit(0);
  }
  soap_init(&soap);

  strcpy(buf, argv[1]);

  soap_call_ns__StructArrayTest(&soap, server,"", buf, &result);
  if (soap.error)  {
    soap_print_fault(&soap, stderr);
    printf("soap wrong: %d, \n please inform the administrator!\n",soap.error);
    exit(1);
  }
  int i;
  for (i=0; i<result.__size; i++)
     printf ("jobid: %d jobStatus:%d, cpuTime:%s, wallTime:%s\n",result.__ptr[i]->jobId,result.__ptr[i]->status,result.__ptr[i]->cpuTime, result.__ptr[i]->wallTime);

  soap_destroy(&soap);
  soap_end(&soap);
  return 1;
}

编译完成后,运行客户端程序,在运行结束后,服务器和客户端的当前目录下会有SENT.log和RECV.log两个文件,可以用来查来两端收发消息的内容。

gsoap一次可以传递的信息的大小是有缺省规定的,但可以修改。可查看gsoap手册。

带gsoap-2.8源码,基于服务器客户端的实例,带自动生成服务客户端代码的批处理程序,及如何使用。带自己学习参考的教程; 0.解压附件,soapInterface.bat所在路径不得含中文 空格 1.新建头文件 取soapInterface.bat文件的同名:soapInterface.h 文件内编写接口,具体说明看附件参考的教程 //gsoap ns service name: gservice //gsoap ns service style: rpc int ns__add(int num1, int num2, int* result ); int ns__sub(int num1, int num2, int* result ); int ns__mult( int num1, int num2, int *result); int ns__divid( int num1, int num2, int *result); 2.从附件内gsoap-2.8包中搜索复制stdsoap2.h,stdsoap2.cpp,soapcpp2.exe, 存放于soapInterface.bat同级目录 3.双击soapInterface.bat运行。生成gClientSoap,gServerSoap两个文件夹,分别复制到服务器工程与客户端工程中使用 4.gClientSoap,gServerSoap两个文件夹内用到的文件功能说明,更多参考附件教程 1)soapC.cpp , soapH.h//soap的序列和反序列代码,它已经包含了soapStub.h 2)soapServer.c ppsoapServerLib.cpp //服务器端代码(纯C代码是soapServer.c soapServerLib.c ),soapServerLib.cpp文件则只是简单地包含soapServer.cpp和soapC.cpp 3)soapClient.cpp soapClientLib.cpp//客户端代码(纯C代码是soapClient.csoapClientLib.c ),soapClientLib.cpp文件则只是简单地包含soapClient.cpp和soapC.cpp 4) soapStub.h // soap的存根文件,定义了我们编写的头文件里对应的远程调用模型 5) add.nsmap //XML服务命名空间 6)服务器端要载入的文件有:soapServer.cpp,soapC.cpp,stdsoap2.cpp; 要包含的文件有:gservice.nsmap,soapH.h; 客户端要输入的文件有: soapClient.cpp,soapC.cpp,stdsoap2.cpp; 要包含的文件有:gservice.nsmap,soapH.h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值