一、 前言

本篇讲述如何通过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

  1. //gsoap ns service name: wscplus
  2. //gsoap ns service style: rpc
  3. //gsoap ns service namespace: http://localhost:10010/wscplus.wsdl
  4. //gsoap ns service location: http://localhost:10010
  5. //gsoap ns schema namespace: urn:wscplus
  6. 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接口

  1. int ns__hellowebservice(struct soap* soapObject, char* param, char** result)
  2. {
  3. wchar_t* param1 = MulityByteToWideChar(CP_UTF8, param);
  4. printf("接收到Java客户端传过来的参数-param: %s\n", WideCharToMulityByte(CP_ACP, param1));
  5. *result = WideCharToMulityByte(CP_UTF8, L"abKJLcd123e12一大堆中文输出参数");
  6. return SOAP_OK;
  7. }

接口实现函数的第一个参数是struct soap* soapObject。后面的参数与helloWebService.h中定义的接口一致。为了保证中文传输不乱码,接收的参数和返回值都做了编码转换。

Step5 实现http_get函数,返回wsdl文件信息

// 编写get响应请求,目的是为了在浏览器中输入url能看到wsdl文件。

// 也方便在soapUI等Webservice接口调试工具中能直接调用定义的接口。

  1. int http_get(struct soap* soapObject)
  2. {
  3. FILE*fd = NULL;
  4. // wscplus.wsdl 是执行soapcpp2.exe命令时生成的。把他拷贝到了当前目录下。
  5. fd = fopen("wscplus.wsdl", "rb"); //open WSDL file to copy
  6. if (!fd)
  7. {
  8. return 404; //return HTTP not found error
  9. }
  10. soapObject->http_content = "text/xml"; //HTTP header with text /xml content
  11. soap_response(soapObject, SOAP_FILE);
  12. for(;;)
  13. {
  14. size_t r = fread(soapObject->tmpbuf,1, sizeof(soapObject->tmpbuf), fd);
  15. if (!r)
  16. {
  17. break;
  18. }
  19. if (soap_send_raw(soapObject, soapObject->tmpbuf, r))
  20. {
  21. break; //cannot send, but little we can do about that
  22. }
  23. }
  24. fclose(fd);
  25. soap_end_send(soapObject);
  26. return SOAP_OK;
  27. }

Step6 发布WebService服务

  1. int _tmain(int argc, _TCHAR* argv[])
  2. {
  3. struct soap soapObject;
  4. soap_init(&soapObject);
  5. soap_set_mode(&soapObject, SOAP_C_UTFSTRING);
  6. soapObject.fget = http_get;
  7. soap_set_namespaces(&soapObject, namespaces);
  8. int ret = soap_bind(&soapObject, NULL, 10010, 100);
  9. if (ret < 0)
  10. {
  11. return -1;
  12. }
  13. while (true)
  14. {
  15. // 阻塞线程,等待外部请求
  16. ret = soap_accept(&soapObject);
  17. if (ret < 0)
  18. {
  19. return -1;
  20. }
  21. soap_serve(&soapObject);
  22. soap_end(&soapObject);
  23. }
  24. return 0;
  25. }

四、 Java客户端开发

Step1建好Java项目,导入CXF lib目录下的Jar包。

不能不说Java的开源组件太好用,傻瓜式开发。C++的gsoap太麻烦了。

Step2 开发客户端代码, 调用WebService接口。

  1. import java.nio.charset.Charset;
  2. import java.rmi.RemoteException;
  3. import javax.xml.namespace.QName;
  4. import javax.xml.rpc.ParameterMode;
  5. import javax.xml.rpc.ServiceException;
  6. import org.apache.axis.client.Call;
  7. import org.apache.axis.client.Service;
  8. import org.apache.axis.encoding.XMLType;
  9. public class StartupClient
  10. {
  11. public static void main(String[] args)
  12. {
  13. try
  14. {
  15. String endpoint = "http://localhost:10010/wscplus?wsdl";
  16. Service service = new Service();
  17. Call call = (Call)service.createCall();
  18. call.setTargetEndpointAddress(endpoint);
  19. // 设置调用的接口,指定输入参数,输出参数
  20. call.setOperationName(new QName("urn:wscplus", "hellowebservice"));
  21. call.addParameter("param", XMLType.XSD_STRING, ParameterMode.IN);
  22. call.addParameter("result", XMLType.XSD_STRING, ParameterMode.OUT);
  23. call.setReturnType(XMLType.XSD_STRING);
  24. String str = "237anastasiaABG293729一大堆中文输入参数";
  25. String strParam = new String(str.getBytes(Charset.forName("UTF-8")));
  26. String result = (String)call.invoke(new Object[]{strParam});
  27. System.out.println("获取C++服务端返回值-result: " + result);
  28. }
  29. catch (ServiceException e)
  30. {
  31. e.printStackTrace();
  32. }
  33. catch (RemoteException e)
  34. {
  35. e.printStackTrace();
  36. }
  37. }
  38. }

五、 调试验证

先启动服务端,在eclipse中启动客户端单步调试,可以看输出参数,返回值信息。

C++与Java通过WebService通信(下)的更多相关文章

  1. bugzilla4的xmlrpc接口api调用实现分享: xmlrpc + https + cookies + httpclient +bugzilla + java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能

    xmlrpc .  https . cookies . httpclient.bugzilla . java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能,网上针对bugzilla的实现很 ...

  2. C++与Java通过WebService通信(上)

    一. 前言 本篇讲述如果通过C++客户端访问Java服务端发布的SOAP模式的WebService接口.文档中的样例代码拷贝出去即可运行,所有的代码都是本地测试OK的:本文不但解决了接口调用的问题,同 ...

  3. Flex通信-Java服务端通信实例

    转自:http://blessht.iteye.com/blog/1132934Flex与Java通信的方式有很多种,比较常用的有以下方式: WebService:一种跨语言的在线服务,只要用特定语言 ...

  4. Java创建WebService服务及客户端实现(转)

    简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...

  5. Java调用webservice接口方法

                             java调用webservice接口   webservice的 发布一般都是使用WSDL(web service descriptive langu ...

  6. Axis2 webservice 之使用java调用webservice

    在上一篇中写了一个简单了webservice,实现了一个sayHello功能.那么webservice写好之后我们如何使用Java程序来调用webservice呢? 一.java调用的webservi ...

  7. C# 开发XML Web Service与Java开发WebService

    一.web service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量 ...

  8. Java创建WebService服务及客户端实现

    简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...

  9. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

随机推荐

  1. Gitbucket—快速建立自己的Github

    GitBucket是一个用Scala语言编写的类似Github的应用,界面非常相似.它非常容易安装–容易到你只需要把它的war文件扔到tomcat中,然后启动tomcat就直接可以访问了.或者直接ja ...

  2. WinFom中经典小游戏(含源码)

    最近整理了若干经典的小游戏,无聊时可以打发时间.程序本身不大,练手非常不错,主要是GDI编程,主界面地址如下图所示 源码下载方式 1,关注微信公众号:小特工作室(也可直接扫描签名处二维码) 2,发送: ...

  3. 【记录】.net 通用log4net日志配置

    asp.net mvc 1.引入log4netNuGet包. 2.修改Global.asax下的Application_Start方法.加入log4net.Config.XmlConfigurator ...

  4. php 链接mysql的三种方式对比

    PHP连接Mysql的三种方式: 1.原生的连接方式  原生的连接方式是面向过程的写法 <?php $host = 'localhost'; $database = 'test'; $usern ...

  5. js创建数组的三个方式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 手把手教你在Ubuntu上分别安装Nginx、PHP和Mysql

    手把手教你在Ubuntu上分别安装Nginx.PHP和Mysql

  7. 两种简单的方法Docker构建LANMP

    在初步入门学习Docker的过程中一步步了解了Docker容器在团队开发中所起到的作用,一边学习一边操作基本命令,当然到现在还处于一个擦边的入门阶段. 尝试一下用Docker构建一个集成开发环境. S ...

  8. MySQL的常见存储引擎介绍与参数设置调优

    MySQL常用存储引擎之MyISAM 特性: 1.并发性与锁级别 2.表损坏修复 check table tablename repair table tablename 3.MyISAM表支持的索引 ...

  9. javascript中快速求数组的全部元素的相加之和

    js中快速求数组的全部元素的相加之和: var arr = [1,2,3,4,5];var sum = eval(arr.join('+')); console.log(sum); 运行结果: 15

  10. Kotlin——基础的函数/方法详解

    对于Kotlin中的函数来说,和JavaScript或者Lua这些语言很像,它有着这些语言的特性.但是也与这些语言就着许多不同之处.或许你更了解Java语言,然而对于Java语言来说,它不是不是闭包这 ...