C++调用webService服务,解决中文乱码和文件上传问题

前言

    之前写了一篇c++发布webService服务,可惜阅读量极少,但是也确实帮助了一位有需要的人,也算是一点点欣慰。现在我再写一篇c++调用webService服务篇,包括中文传输和文件上传。

    项目需要这个东西,我写一个代码示例,具体的项目代码肯定不会发布出来。遇到的坑有不少,好在一一解决了,该科学上网还是得科学上网,能解决不少问题。可恶的是文件上传的代码示例网络上居然有人用来弄积分,还要34积分,真的是可恶,一点开源精神都没有,这里要小小的鄙视一下这类人。


一、gsoap2.8

这里我下载的gsoap是最新的2.8,我们如果要上传中文的话,会遇到乱码问题。这里我们要解决一下乱码问题,不然c++上传到webService接口中会显示乱码。我这里的接口是用java写的接口,这里我为了简单说明,我会将中文参数传递和文件整合到一起,就不逐一的演示了。

这里我的接口代码我是使用springboot用cxf框架发布的webService接口,这不是重点。

java接口代码示例:

public String fileCall(DataHandler file, String params) {
        file.getInputStream();
        System.out.printLin(params);
}

我们首先要知道这个接口的wsdl地址,需要使用gsoap根据这个wsdl地址生成相关的代理类。

重点:在下面的目录中新建一个api.bat(名字可以随便起,建议使用项目名称)

原因:这里涉及到了中文字符串的调用,所以需要这样进行处理。

这里我是在win64位代码编写的,如果有需求也可以在win32下生成,步骤是一样的。

文件内容:

xsd__string = | std::wstring | wchar_t*

在当前目录下打开cmd命令窗口,shift+鼠标左键

执行如下的命令:

一般来说都是会成功的,只要严格按照我的要求来做

//这是第一条命令,执行完毕后会出现api.h头文件

.\wsdl2h.exe -o .\api.h http://localhost:8081/api/services/api?wsdl -t api.bat     

//这是第二条命令,执行完后会出现如下的文件

.\soapcpp2.exe -C .\api.h -I .\api\ -x


二、编写测试调用代码

现在最关键的地方已经来了,这里还要再三的批评一下某些人,c++调用webService的代码竟然还要下载收积分!真的是可恶。

而且国内的某度搜索也不给力,搞的我直接用了科学上网,再使用我的poor English 终于得到一篇较为完美的c++上传文件的文档,自己再骚味改动一下就迫不及待地发布出来了。

好了,废话不多说,直接上码吧!

导入相关的头文件,这里注意的是,还需要导入  gsoap 文件夹内的两个文件,还有导入文件不要导入多的!

导入的文件:

这里不要自作聪明使用Clion,老老实实使用VS2010或者其他年份的版本,同样的代码,VS可以,Clion报错,说是找不到相关的定义,这里我就不吐槽了。

编写测试代码,我们编写一个Test.cpp,代码如下

我在给webService服务上传了一个本地文件,然后还传递了一些参数信息

xsd__base64Binary这个东西就是生成代码的关键类

#include <iostream>
#include <stdio.h>
#include "soapH.h"
#include "IApiWebServiceSoapBinding.nsmap"
#include <fstream>
using namespace std;
using std::ifstream;

int main(){
    //SOAP客户端
    struct soap m_oSoap;

	//测试文件调用对象
	class ns1__fileCall fileCallObject;

	//测试文件返回对象
	class ns1__fileCallResponse fileCallResponse;

    //这里我们转到fileCallObject上,发现需要使用这个类
	class xsd__base64Binary remoteFile;

	//申明一个内存
	unsigned char *buffer;
	int fileLen;
	FILE *file;
    
    //这个rb是什么意思我也不知道
	file = fopen("D:\\test\\测试文件上传文本文档.txt","rb");
    
	if(!file){
		fprintf(stderr, "Unable to open file %s", "测试文件上传文本文档.txt");
        return 0;
	}
	//GET FILE LENGTH
    fseek(file, 0, SEEK_END);
    fileLen=ftell(file);
    fseek(file, 0, SEEK_SET);

    //ALLOCATE MEMORY
    buffer=(unsigned char *)soap_malloc(&m_oSoap,fileLen+1);
    if (!buffer)
    {
        fprintf(stderr, "Memory error! :( ");
        fclose(file);
        return 0;
    }

    //READ FILE CONTENTS INTO BUFFER AND CLOSE FILE
    fread(buffer, fileLen, 1, file);
    fclose(file);

	remoteFile.__ptr=buffer;
	remoteFile.__size=fileLen;
    //soap初始化
    soap_init(&m_oSoap);
    //调用函数参数赋值

	fileCallObject.file = &remoteFile;
	fileCallObject.params=L"测试中文信息";

    //发送webService请求
	int nResult = soap_call___ns1__fileCall(&m_oSoap,NULL,NULL,&fileCallObject,fileCallResponse);
	

    if (SOAP_OK == nResult) {
        //输出返回结果
        wchar_t *strResult = fileCallResponse.return_;
		wcout.imbue(locale("chs"));
		wcout<<"wcout:"<<strResult<<endl;
       
    }
    //关闭soap
    soap_destroy(&m_oSoap);
    soap_end(&m_oSoap);
    soap_done(&m_oSoap);
    system("pause");

    return 0;

}

ctrl+F5,使用VS编译一下,编译成功后,双击运行

我在本地接口打了断点,很清楚的就可以看到这个len长度和buf信息。

中文参数,可以看到我的传参是prams =测试中文信息

到了这一步就大功告成!让我们一起鄙视那些需要积分下载的人吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值