C++與Java通過WebService通訊(下)

來源:互聯網
上載者:User

標籤:c++   java   

一、 前言

本篇講述如何通過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:wscplusint 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通訊(下)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.