C++与Java通过WebService通信(下)
一、 前言
本篇讲述如何通过Java客户端访问C++服务端发布的SOAP模式的WebService接口。文档中的样例代码拷贝出去即可运行,所有的代码都是本地测试OK的;本文不但解决了接口调用的问题,同时解决了中文乱码的问题。
二、 环境准备
1、 CXF组件:Java端用于发布WebService服务的开源组件,内部自带jetty Web容器。
2、 Gsoap组件:C++端用户访问WebService服务的组件。使用的是gsoap-2.8。这两个组件可以直接google,官网下载。
3、 Eclipse:Java开发IDE。
4、 VS 2010:C++开发IDE。
三、 C++服务端开发
Step1 定义WebService接口文件helloWebService.h
//gsoap ns service name: wscplus
//gsoap ns service style: rpc
//gsoap ns service namespace: http://localhost:10010/wscplus.wsdl
//gsoap ns service location: http://localhost:10010
//gsoap ns schema namespace: urn:wscplus
int ns__hellowebservice(char* param, char** result);
定义接口需要注意:
1、 接口返回值是int型.
2、 接口名称定义格式为 ns__xxx。
3、 输入参数是字符串指针,输出参数是指针的指针。同样,可以通过json串传递更多的内容。
4、 函数头注释按给的样例定义。在注释中定义服务IP,端口,wsdl文件名。如果函数头未按指定格式定义,使用soapcpp2.exe转换时将产生不了wsdl文件。
Step2使用gsoap-2.8\gsoap\bin\win32\ soapcpp2.exe生成服务端代码。
生成了如下文件:
Step3 将头.h.cpp\nsmap拷贝到VS2010工程中,编译。
编译不过,将soapServerLib.cpp中的#include “soapC.cpp”、#include “soapServer.cpp”注释掉。
Step4实现WebService接口
// 实现WebService接口
int ns__hellowebservice(struct soap* soapObject, char* param, char** result)
{
wchar_t* param1 = MulityByteToWideChar(CP_UTF8, param);
printf("接收到Java客户端传过来的参数-param: %s\n", WideCharToMulityByte(CP_ACP, param1));
*result = WideCharToMulityByte(CP_UTF8, L"abKJLcd123e12一大堆中文输出参数");
return SOAP_OK;
}
接口实现函数的第一个参数是struct soap* soapObject。后面的参数与helloWebService.h中定义的接口一致。为了保证中文传输不乱码,接收的参数和返回值都做了编码转换。
Step5 实现http_get函数,返回wsdl文件信息
// 编写get响应请求,目的是为了在浏览器中输入url能看到wsdl文件。
// 也方便在soapUI等Webservice接口调试工具中能直接调用定义的接口。
int http_get(struct soap* soapObject)
{
FILE*fd = NULL;
// wscplus.wsdl 是执行soapcpp2.exe命令时生成的。把他拷贝到了当前目录下。
fd = fopen("wscplus.wsdl", "rb"); //open WSDL file to copy
if (!fd)
{
return 404; //return HTTP not found error
}
soapObject->http_content = "text/xml"; //HTTP header with text /xml content
soap_response(soapObject, SOAP_FILE);
for(;;)
{
size_t r = fread(soapObject->tmpbuf,1, sizeof(soapObject->tmpbuf), fd);
if (!r)
{
break;
}
if (soap_send_raw(soapObject, soapObject->tmpbuf, r))
{
break; //cannot send, but little we can do about that
}
}
fclose(fd);
soap_end_send(soapObject);
return SOAP_OK;
}
Step6 发布WebService服务
int _tmain(int argc, _TCHAR* argv[])
{
struct soap soapObject;
soap_init(&soapObject);
soap_set_mode(&soapObject, SOAP_C_UTFSTRING);
soapObject.fget = http_get;
soap_set_namespaces(&soapObject, namespaces);
int ret = soap_bind(&soapObject, NULL, 10010, 100);
if (ret < 0)
{
return -1;
}
while (true)
{
// 阻塞线程,等待外部请求
ret = soap_accept(&soapObject);
if (ret < 0)
{
return -1;
}
soap_serve(&soapObject);
soap_end(&soapObject);
}
return 0;
}
四、 Java客户端开发
Step1建好Java项目,导入CXF lib目录下的Jar包。
不能不说Java的开源组件太好用,傻瓜式开发。C++的gsoap太麻烦了。
Step2 开发客户端代码, 调用WebService接口。
import java.nio.charset.Charset;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
public class StartupClient
{
public static void main(String[] args)
{
try
{
String endpoint = "http://localhost:10010/wscplus?wsdl";
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(endpoint);
// 设置调用的接口,指定输入参数,输出参数
call.setOperationName(new QName("urn:wscplus", "hellowebservice"));
call.addParameter("param", XMLType.XSD_STRING, ParameterMode.IN);
call.addParameter("result", XMLType.XSD_STRING, ParameterMode.OUT);
call.setReturnType(XMLType.XSD_STRING);
String str = "237anastasiaABG293729一大堆中文输入参数";
String strParam = new String(str.getBytes(Charset.forName("UTF-8")));
String result = (String)call.invoke(new Object[]{strParam});
System.out.println("获取C++服务端返回值-result: " + result);
}
catch (ServiceException e)
{
e.printStackTrace();
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
}
五、 调试验证
先启动服务端,在eclipse中启动客户端单步调试,可以看输出参数,返回值信息。
C++与Java通过WebService通信(下)的更多相关文章
- bugzilla4的xmlrpc接口api调用实现分享: xmlrpc + https + cookies + httpclient +bugzilla + java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能
xmlrpc . https . cookies . httpclient.bugzilla . java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能,网上针对bugzilla的实现很 ...
- C++与Java通过WebService通信(上)
一. 前言 本篇讲述如果通过C++客户端访问Java服务端发布的SOAP模式的WebService接口.文档中的样例代码拷贝出去即可运行,所有的代码都是本地测试OK的:本文不但解决了接口调用的问题,同 ...
- Flex通信-Java服务端通信实例
转自:http://blessht.iteye.com/blog/1132934Flex与Java通信的方式有很多种,比较常用的有以下方式: WebService:一种跨语言的在线服务,只要用特定语言 ...
- Java创建WebService服务及客户端实现(转)
简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...
- Java调用webservice接口方法
java调用webservice接口 webservice的 发布一般都是使用WSDL(web service descriptive langu ...
- Axis2 webservice 之使用java调用webservice
在上一篇中写了一个简单了webservice,实现了一个sayHello功能.那么webservice写好之后我们如何使用Java程序来调用webservice呢? 一.java调用的webservi ...
- C# 开发XML Web Service与Java开发WebService
一.web service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量 ...
- Java创建WebService服务及客户端实现
简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...
- Flex通信-与Java实现Socket通信实例
Flex通信-与Java实现Socket通信实例 转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...
随机推荐
- 洛谷P1879 [USACO06NOV]玉米田Corn Fields【状压DP】题解+AC代码
题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ...
- Inspinia_admin-V2.3原版(英文)
Inspinia_admin-V2.3原版(英文) Inspinia_admin-V2.3 BootStrap原版(英文) 原版是老外开发的,结果 国内某人翻译成中文版进行二次开发 卖998 演示地址 ...
- Python面向对象篇(3)-封装、多态、反射及描述符
1. 多态 多态,最浅显的意识就是同一事物具有多种形态,这很好理解,动物是一个大类,猫类属于动物类,狗类属于动物类,人也是属于动物类,那能理解成,猫.狗.人是一样的吗?当然不是,还有,水,分为液体.固 ...
- <url-pattern>/</url-pattern>和<url-pattern>/*</url-pattern>区别
<url-pattern>/</url-pattern>表示的为只匹配/login和/demo后面不带.xxx的网页 <url-pattern>/*</url ...
- EmguCV中图像类型进行转换
1. Bitmap:类型不在 Emgucv命名空间中 2. Image<TColor, TDepth> 3. Mat: 4. UMat: 高 ...
- CodeForces - 727E Games on a CD 字符串Hash
题意:有n个单词,每个单词长度为k,顺时针将它们写成一个圆圈串.现在知道g个长度为k的单词,是否可以从这g个单词中选择n个形成这个圆圈串?如果有多个答案,任意输出一个. 思路 可以发现,如果枚举第一个 ...
- uploadify上传文件(2)--基础语法
隔了好久,因为最近搬家,离开从小生活的城市,来到杭州.找工作.找房子等诸多事宜耽误了这篇文章许久.今天难得闲暇在旅馆中完成uploadify上传文件系列的第二篇--uploadify使用的基础语法. ...
- Math.round(11.5)等于多少? Math.round(-11.5)等于多少?
1.先说下怎么理解 round()方法可以这样理解: 将括号内的数+0.5之后,向下取值, 比如:round(3.4)就是3.4+0.5=3.9,向下取值是3,所以round(3.4)=3; roun ...
- sparklyr包:实现Spark与R的接口+sparklyr 0.5
本文转载于雪晴数据网 相关内容: sparklyr包:实现Spark与R的接口,会用dplyr就能玩Spark Sparklyr与Docker的推荐系统实战 R语言︱H2o深度学习的一些R语言实践-- ...
- 云摘录︱Word2Vec 作者Tomas Mikolov 的三篇代表作解析
本文来源于公众号paperweekly 谈到了word2vec作者的三篇论文: 1.Efficient Estimation of Word Representation in Vector Spac ...