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中启动客户端单步调试,可以看输出参数,返回值信息。

时间: 2025-01-04 15:14:13

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

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

xmlrpc .  https . cookies . httpclient.bugzilla . java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能,网上针对bugzilla的实现很少,针对xmlrpc的有但是基本都是http协议的,https下的认证处理比较麻烦,而且会话保持也是基本没有太多共享,所以本人决定结合xmlrpc\bugzilla官方文档,网友文章,结合个人经验总结而成,已经在window2007 64+jdk7位机器上调试通过 手把手教你如何实现: 第一步: 在

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

一. 前言 本篇讲述如果通过C++客户端访问Java服务端发布的SOAP模式的WebService接口.文档中的样例代码拷贝出去即可运行,所有的代码都是本地测试OK的:本文不但解决了接口调用的问题,同时解决了中文乱码的问题. 二. 环境准备 1. CXF组件:Java端用于发布WebService服务的开源组件,内部自带jetty Web容器. 2. Gsoap组件:C++端用户访问WebService服务的组件.使用的是gsoap-2.8.这两个组件可以直接google,官网下载. 3. Ec

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

Flex与Java通信的方式有很多种,比较常用的有以下方式: WebService:一种跨语言的在线服务,只要用特定语言写好并部署到服务器,其它语言就可以调用 HttpService:通过http请求的形式访问服务器 RmoteObject:通过AMF协议,以二进制的形式交互数据 Socket:套接字协议,服务器和客户端以IO的形式交互数据 上面几种各有个的优势:WebService常用于跨语言调用,不过解析协议需要花不少时间,运行速度不快:HttpService类似于Ajax:通常RmoteO

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

简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto.com/art/200908/147125.htm,不同的语言平台对WebService都有实现,Java的WebService实现,比较流行的有Axis2.Jaxws,本文介绍的是Axis2. Axis2下载和部署 Axis2是Apache开发的一个开源项目,再次感叹Apache的伟大! 下载地址

Java实现串口通信的小样例

用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip.当中要用到三个文件,配置例如以下: 1.comm.jar放置到 JAVA_HOME/jre/lib/ext; 2.win32com.dll放置到 JAVA_HOME/bin; 3.javax.comm.properties 两个地方都要放 jre/lib(也就是在JAVA目录下的jre) JAVA_HOME/jre/lib 说一下我应用的环境.电子秤称重时,计算机通过串口给称重控

纯 Java 开发 WebService 调用测试工具(wsCaller.jar)

注:本文来自hacpai.com:Tanken的<纯 Java 开发 WebService 调用测试工具(wsCaller.jar)>的文章 基于 Java 开发的 WebService 测试工具,不像上文的 iWallpaper.jar 只能实现在 Windows 系统下的功能,此工具发挥了 Java 跨平台的优势,亲测可在 Windows.Mac OS 及 Linux 下运行及使用.简单易用的专门用于测试 WebService 的小工具,在 2003 版 wsCaller.jar 的基础上

基于networkcomms V3通信框架的c#服务器与java客户端进行通信之Protobuf探讨

在上一篇 基于networkcomms V3通信框架的c#服务器与java客户端进行通信探讨  中探讨了在C#端与Java端通信中传递字符,有朋友提到如果传递int类型的整数,会出现编码的问题. 到网上找到了一篇文章< 使用protobuf进行C#与Java通信 >进行学习 ,使用protobuf进行编码,传递数据,好像这样可以避免编码的问题. (虽然编码问题解决了,但是粘包问题并没有解决,有经验的朋友介绍下怎样解决粘包的问题) 服务器端基于networkcomms V3 C#通信框架. ne

Java实现IO通信(服务器篇)

Java实现IO通信(服务器篇) 如何利用java实现我们的通信呢?首先我们了解一下什么是通信?通信的机制是怎样的? 首先来讨论一下什么是通信?通信,指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递,从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法,任意媒质,将信息从某方准确安全地传送到另方.而这里所说的通信,是在同一局域网内,一个用户给其他用户发送信息的过程. 然后通行的机制是怎么样的呢?这里的JavaIO通信是这样的,首先我们需要一台服务器,并有一个或者多个用户

Java之webService知识

Java之webService知识 1 webservice基础知识 1.1 webService请求的本质 一次webService本质请求,如下所示: 1.2 wsdl文档解析 wsdl文档元素结果,及相应关系如下: 2 JDK创建webService的方法 2.1  jdk服务端创建 2.1.1 创建一个java项目和相应的包 2.1.2 创建一个提供webservice服务的接口HelloWs,如下所示 2.1.3 创建接口的实现类HelloWsImpl,如下所示 2.1.4 创建一个j