In the MFC/C++
environment, there are several libraries/tools can be used to integrate with
Java Web Service. They are ATL Server, Windows Web Service API and gSoap.
1, ATL Server
ATL Server is C++
Template based technology in Vistual Studio environment.It provides an utility
tool to generate proxy code for Web Service client. From Visual Studio 2008,
Mirosoft open sourced it, and its official Web site is http://atlserver.codeplex.com.
We can download the ATL_Server_Source_and_Headers_9_0_70425_Alpha.zip. After unzipping this file, we can find a
solution file under the source sub folder for this tool. It is in the VS
2005 version, which need converted into
VS 2008 version once we double click it to open it. Open the solution
file, add the ATL Server include folder in the property
Then build this sproxy.sln
, we can get the sproxy.exe utility.
In Microsoft MSDN,
We can find some useful link about how to use the sproxy.exe.
sproxy [ options ] [
/out:outputfile ] input_location
The input_location can be a local WSDL file or HTTP link for a WSDL.
For example:
sproxy /wsdl http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL
will generate a header file
WeatherWS.h.We can add this file in our Web Service Client project to
access like:
#include "WeatherWS.h"
using namespace WeatherWS;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
CoInitialize(NULL);
HRESULT hr = S_OK;
CWeatherWST<CSoapSocketClientT<>> * m_srv = new CWeatherWST<CSoapSocketClientT<>>;
CComBSTR cityCode = "";
CComBSTR userId = "";
CComBSTR * bstrOut;
int size;
hr = m_srv->getWeather(cityCode, userId,
(BSTR * *)&bstrOut, &size);
if(FAILED(hr))
{
}
else
{
std::cout << bstrOut->m_str << std::endl;
}
if (m_srv
!= NULL)
delete
m_srv;
CoUninitialize();
return 0;
}
This snippet of code can run successfully.
But when we generate some other Web Service WSDL file, the
generated file will cause runtime exception. We created the Web Service – User
Detail to get available application for specific user. The WSDL content for
this Web Service is listed following:
<?xml
version="1.0" encoding="UTF-8" ?>
-
<wsdl:definitions
name="UserDetailServiceImplService" targetNamespace="http://security.ipns.enterprise.argushealth.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://security.ipns.enterprise.argushealth.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-
<wsdl:types>
-
<xs:schema
elementFormDefault="unqualified" targetNamespace="http://security.ipns.enterprise.argushealth.com/" version="1.0" xmlns:tns="http://security.ipns.enterprise.argushealth.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="getAvailableApplications" type="tns:getAvailableApplications" />
<xs:element name="getAvailableApplicationsResponse" type="tns:getAvailableApplicationsResponse" />
-
<xs:complexType
name="getAvailableApplications">
-
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string" />
</xs:sequence>
</xs:complexType>
-
<xs:complexType
name="getAvailableApplicationsResponse">
-
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:application" />
</xs:sequence>
</xs:complexType>
-
<xs:complexType
name="application">
-
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
<xs:element minOccurs="0" name="url" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
-
<wsdl:message
name="getAvailableApplications">
<wsdl:part element="tns:getAvailableApplications" name="parameters" />
</wsdl:message>
-
<wsdl:message
name="getAvailableApplicationsResponse">
<wsdl:part element="tns:getAvailableApplicationsResponse" name="parameters" />
</wsdl:message>
-
<wsdl:portType
name="UserDetailService">
-
<wsdl:operation
name="getAvailableApplications">
<wsdl:input message="tns:getAvailableApplications" name="getAvailableApplications" />
<wsdl:output message="tns:getAvailableApplicationsResponse" name="getAvailableApplicationsResponse" />
</wsdl:operation>
</wsdl:portType>
-
<wsdl:binding
name="UserDetailServiceImplServiceSoapBinding" type="tns:UserDetailService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
-
<wsdl:operation
name="getAvailableApplications">
<soap:operation soapAction="" style="document" />
-
<wsdl:input
name="getAvailableApplications">
<soap:body use="literal" />
</wsdl:input>
-
<wsdl:output
name="getAvailableApplicationsResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
-
<wsdl:service
name="UserDetailServiceImplService">
-
<wsdl:port
binding="tns:UserDetailServiceImplServiceSoapBinding" name="UserDetailServiceImplPort">
<soap:address location="http://172.16.23.25:9081/user-application-ws/UserDetail" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
After
running
sproxy
/wsdl http://172.16.23.25:9081/user-application-ws/UserDetail?wsdl
We add the generated file UserDetailServiceImplService.h to
RSOClient project, use the following snippet of code to access the Web Service:
#include "UserDetailServiceImplService.h"
using namespace UserDetailServiceImplService;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
CoInitialize(NULL);
HRESULT hr = S_OK;
CUserDetailServiceImplServiceT<CSoapSocketClientT<>> * m_srv
= new CUserDetailServiceImplServiceT<CSoapSocketClientT<>>;
CComBSTR userId = "charles";
CComBSTR * bstrOut;
int size;
getAvailableApplications arg;
application AvailableApplicationsResponse;
application* p = &AvailableApplicationsResponse;
application** ppAvailableApplicationsResponse = &p;
arg.arg0 = L"charles";
hr = m_srv->_getAvailableApplications(arg, ppAvailableApplicationsResponse,
&size);
if(FAILED(hr))
{
std::cout<< L"fail"
<< std::endl;
}
else
{
for (int i = 0; i < size; i++)
{
std::cout << ppAvailableApplicationsResponse[i]->name
<< std::endl;
std::cout << ppAvailableApplicationsResponse[i]->url
<< std::endl;
}
}
if (m_srv
!= NULL)
delete
m_srv;
CoUninitialize();
}
hr = m_srv->_getAvailableApplications(arg, ppAvailableApplicationsResponse,
&size);
Always goes to
if(FAILED(hr))
{
std::cout<< L"fail"
<< std::endl;
}
After carefully debugging we found that the generated proxy is
sending incorrect SOAP content. From the captured the network package, we can
see
There are one more <getAvailableApplications>
sub element under <getAvailableApplications>. But from the WSDL file, the
getAvailableApplications element should be
The element arg0 is the direct child element of
getAvailableApplications. When we evaluated the gSOAP, we found that gSOAP
generates the correct format.
2, Windows Web Service API
WWSAPI is a native-code
implementation of SOAP which provides core network communication functionality
by supporting a set of the WS-* and .NET-* family of protocols. WWSAPI is
designed to be used by components/applications which fall into one of the
following categories:
- Native code mandate
- Require minimal
dependencies
- Require minimal startup
time
- Memory constrained
environments
Windows Web Services
API (WWSAPI) is an operating-system component of the following operating
systems:
- Windows 7
- Windows
Server 2008 R2
- XP SP3
- Vista
Windows Web Services
API sounds like a perfect option for us,
all the original download link are not available now. It needs us send formal
business email to Microsoft to get redistributable installers.
We mainly referenced to this
official blog of MSDN . http://blogs.msdn.com/b/windowssdk/archive/2009/10/20/building-web-services-on-windows-with-c.aspx
3, gSOAP
The official web site for gSOAP is http://sourceforge.net/projects/gsoap2.
From there we can learn that:
The gSOAP toolkit is a portable C and C++ software
development toolkit for XML Web services and generic XML data bindings.
Easy-to-use XML auto-serialization allows you to directly integrate C and C++
data with XML. Includes WSDL/XSD schema binding and auto-coding tools,
stub/skeleton compiler, Web servers (with SSL), integrated XML processing with
schema validation, fast MIME/MTOM streaming, SOAP and REST, WS-* protocols
(WS-Security, WS-Policy, etc), XML-RPC and JSON serialization.
Currently the stable version is 2.8.8.After
download and unzip the gsoap_2.8.8.zip file, we can find there
are two binary tools under the sub
folder gsoap/bin/win32:
wsdl2h.exe
soapcpp2.exe
There
is also source code for them under the src folder. Of course we can build both of them from scratch. There
is VisualStudio2005 folder, under which the Readme is very importance.
Follow the Readme, we can also
build the two tools by ourselves .
The two tools has some function as sproxy.exe in ATL Server. The difference is we need do it with two
steps. First we use wsdl2h to generate a header file , then use soapcpp2 to
generate the files we need use in our project base on this header file. For example:
1, wsdl2h -o userservice.h -n
namespacename URL or file name
the generatd userservice.h file will be used in the
next step.
2, soapcpp2 userservice.h -C -i -x
-I F:\study_code\mfc\gsoap_2.8.8\gsoap-2.8\gsoap\import
F:\study_code\mfc\gsoap_2.8.8\gsoap-2.8\gsoap\import
is the import folder under the gsoap.
soapcpp2 will generate totally fix files:
- soaph.h
- soapc.cpp
- soapStub.h
- soapUserDetailServiceImplServiceSoapBindingProxy.cpp
- soapUserDetailServiceImplServiceSoapBindingProxy.h
- UserDetailServiceImplServiceSoapBinding.nsmap
After generating the files , we need use the files in our Web
Service client project. Except the generated files, we also need other two
files : stdsoap2.h, stdsoap2.cpp ( they are under the gSoap folder). We can use the following snippet of code :
#include "UserDetailServiceImplServiceSoapBinding.nsmap"
#include "soapUserDetailServiceImplServiceSoapBindingProxy.h"
const char endpoint[] = "http://172.16.23.25:9081/user-application-ws/UserDetail";
CReEngiApps GetApps(const char* userId)
{
CReEngiApps apps;
UserDetailServiceImplServiceSoapBindingProxy proxy(SOAP_XML_INDENT);
rso1__getAvailableApplications rso1__getAvailableApplications_;
rso1__getAvailableApplicationsResponse
rso1__getAvailableApplicationsResponse_;
std::string user = userId;
rso1__getAvailableApplications_.arg0 = & user;
int ret =
proxy.getAvailableApplications(endpoint, NULL,
&rso1__getAvailableApplications_,
&rso1__getAvailableApplicationsResponse_);
if (ret == SOAP_OK)
{
std::vector<rso1__application * > &
applications = rso1__getAvailableApplicationsResponse_.return_;
apps.m_appNum = applications.size();
for (int i=0; i < apps.m_appNum; i++)
{
memcpy(apps.m_apps[i].m_szAppName,
applications[i]->name->c_str(),
strlen(applications[i]->name->c_str()));
memcpy(apps.m_apps[i].m_szAppUrl,
applications[i]->url->c_str(),
strlen(applications[i]->url->c_str()));
}
} else
{
apps.m_appNum = 0;
}
return apps;
}
ATL Server VS gSOAP
1,
ATL Server is C++ template based.Its generated code has lots of template code.
Template code is much harder than normal code to understand.gSOAP generates
simple code, event only C code.
2, ATL Server has
a fatal issue, we found, it generates incorrect SOAP content, which can cause
request failed. So far, the code generated by gSOAP is good, no big issue.
Conclution
gSOAP
is an open source tool can generate portable C/C++ Web Service proxy code.The
generated code is easy to use.
分享到:
相关推荐
20.2.1. Logging changes in condition evaluation 20.2.2. Excluding Resources 20.2.3. Watching Additional Paths 20.2.4. Disabling Restart 20.2.5. Using a Trigger File 20.2.6. Customizing the Restart ...
修炼成Javascript中级程序员必知必会_资源分享
内容概要:本文详细介绍了如何使用MATLAB的深度学习工具箱,在果树病虫害识别任务中从数据准备、模型设计、训练优化到最后的模型评估与应用全流程的具体实施步骤和技术要点。涵盖了MATLAB深度学习工具箱的基本概念及其提供的多种功能组件,如卷积神经网络(CNN)的应用实例。此外,文中还具体讲述了数据集的收集与预处理方法、不同类型的深度学习模型搭建、训练过程中的超参数设定及其优化手段,并提供了病虫害识别的实际案例。最后展望了深度学习技术在未来农业领域的潜在影响力和发展前景。 适合人群:对深度学习及农业应用感兴趣的科研人员、高校师生和相关从业者。 使用场景及目标:①希望掌握MATLAB环境下构建深度学习模型的方法和技术细节;②从事果树病虫害管理研究或实践,寻找高效的自动化解决方案。 阅读建议:在阅读本文之前,建议读者熟悉基本的MATLAB编程环境及初步了解机器学习的相关概念。针对文中涉及的理论和技术难点,可以通过官方文档或其他教程进行补充学习。同时,建议动手实践每一个关键点的内容,在实践中加深理解和掌握技能。
nodejs010-nodejs-block-stream-0.0.7-1.el6.centos.alt.noarch.rpm
机械模型与技术交底书的融合:创新点详解与解析,机械模型加技术交底书,有创新点 ,机械模型; 技术交底书; 创新点,创新机械模型与技术交底书详解
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
nodejs010-nodejs-cmd-shim-1.1.0-4.1.el6.centos.alt.noarch.rpm
西门子四轴卧加后处理系统:828D至840D兼容,四轴联动高效加工解决方案,支持图档处理及试看程序。,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
基于黏菌优化算法(SMA)的改进与复现——融合EO算法更新策略的ESMA项目报告,黏菌优化算法(SMA)复现(融合EO算法改进更新策略)——ESMA。 复现内容包括:改进算法实现、23个基准测试函数、多次实验运行并计算均值标准差等统计量、与SMA对比等。 程序基本上每一步都有注释,非常易懂,代码质量极高,便于新手学习和理解。 ,SMA复现;EO算法改进;算法实现;基准测试函数;实验运行;统计量;SMA对比;程序注释;代码质量;学习理解。,标题:ESMA算法复现:黏菌优化与EO算法融合改进的实证研究
基于MATLAB的Stewart平台并联机器人仿真技术研究与实现:Simscape环境下的虚拟模拟分析与应用,MATLAB并联机器人Stewart平台仿真simscape ,MATLAB; 并联机器人; Stewart平台; 仿真; Simscape; 关键技术。,MATLAB中Stewart平台并联机器人Simscape仿真
Grad-CAM可视化医学3D影像
探索comsol泰勒锥:电流体动力学的微观世界之旅,comsol泰勒锥、电流体动力学 ,comsol泰勒锥; 电流体动力学; 锥形结构; 电场影响,COMSOL泰勒锥与电流体动力学研究
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
PFC6.03D模型动态压缩模拟与SHPB霍普金森压杆系统理论及实验数据处理技术解析,PFC6.03D模型,动态压缩模拟,还包括: SHPB霍普金森压杆系统理论知识介绍,二波法和三波法处理实验数据,提出三波波形,计算动态压缩强度等 ,PFC模型; 动态压缩模拟; SHPB霍普金森压杆系统; 理论介绍; 二波法处理; 三波法处理; 三波波形; 动态压缩强度。,"PFC模型下的动态压缩模拟及SHPB理论实践研究"
ProASCI 开发板原理图,适用于A3P3000
免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
1、文件内容:pykde4-devel-4.10.5-6.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/pykde4-devel-4.10.5-6.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
基于Comsol模拟的三层顶板随机裂隙浆液扩散模型:考虑重力影响的瞬态扩散规律分析,Comsol模拟,考虑三层顶板包含随机裂隙的浆液扩散模型,考虑浆液重力的影响,模型采用的DFN插件建立随机裂隙,采用达西定律模块中的储水模型为控制方程,分析不同注浆压力条件下的浆液扩散规律,建立瞬态模型 ,Comsol模拟; 随机裂隙浆液扩散模型; 浆液重力影响; DFN插件; 达西定律模块储水模型; 注浆压力条件; 浆液扩散规律; 瞬态模型,Comsol浆液扩散模型:随机裂隙下考虑重力的瞬态扩散分析
A simple fast, easy use distributed file system written by golang(similar fastdfs).go-fastdfs