由于在上传报警服务器过车数据时,第三方平台提供了webservice接口。以前用VC++2003做过调用webservice接口,直接在Project菜单下的add web Reference填入相关的名称,VC++2003会自动生成相关的类,在调用的地方只要定义一个实例就可以调用webservice接口了,但是在测试南通卡口数据上传项目时发现,编译时总是提示命名空间不对,后来查找资料发现webservice接口编写不规范会导致webservice接口的 namespace不对。我们不能要求第三方修改webservice接口,只能查找其他方法。于是通过soap调用webservice接口。以下是详细步骤:
1、首先下载安装soapsdk3.0
(http://download.microsoft.com/download/2/e/0/2e068a11-9ef7-45f5-820f-89573d7c4939/soapsdk.exe)。
2、在头文件中引入必要的库的,包含相应的命名空间
#import "msxml4.dll"
using namespace MSXML2;
#import "C:\Program Files\Common Files\MSSoap\Binaries\MSSOAP30.dll" \
exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", \
"_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")
using namespace MSSOAPLib30;
3、在cpp文件中调用soap提供的接口,直接贴代码
try
{
// 与Web服务连接
pDlg->Connector.CreateInstance(__uuidof(HttpConnector30));
// http://10.36.6.4/video/control.asmx?op=WriteTgclJl为调用页面,在URL里指定你的服务器名
pDlg->Connector->Property["EndPointURL"] = "http://10.36.6.4/video/control.asmx?op=WriteTgclJl";
pDlg->Connector->Connect();
// 开始消息,http://10.36.6.4/video/WriteTgclJl为响应函数,
pDlg->Connector->Property["SoapAction"] = "http://10.36.6.4/video/WriteTgclJl";
pDlg->Connector->BeginMessage(); //启动消息句柄
// 创建SoapSerializer对象
pDlg->Serializer.CreateInstance(__uuidof(SoapSerializer30));
//将 serializer 连接到 connector 的输入字符串
pDlg->Serializer->Init(_variant_t((IUnknown*)pDlg->Connector->InputStream));
// 创建ISoapReaderPtr对象
pDlg->Reader.CreateInstance(__uuidof(SoapReader30));
// 创建SOAP消息
pDlg->Serializer->StartEnvelope("","","");
// pDlg->Serializer ->StartEnvelope("","STANDARD","")
pDlg->Serializer->StartBody("");
// 找到WEB函数名
// pDlg->Serializer ->StartElement("WriteTgclJl","","STANDARD","")与前面保持一致
pDlg->Serializer->StartElement("WriteTgclJl","http://10.36.6.4/video/","","");
// 找到第1个参数
pDlg->Serializer->StartElement("s_jlid","http://10.36.6.4/video/","","");
// 输入第1个参数值
char szID[20] = "";
sprintf(szID, "%d", passVehicle.iCarLsh);
pDlg->Serializer->WriteString(szID);
pDlg->Serializer->EndElement();
// 找到第2个参数
pDlg->Serializer->StartElement("s_cbzmc","http://10.36.6.4/video/","","");
// 输入第2个参数值
pDlg->Serializer->WriteString(passVehicle.chCrossingName);
pDlg->Serializer->EndElement();
// 找到第3个参数
pDlg->Serializer->StartElement("s_hphm","http://10.36.6.4/video/","","");
// 输入第3个参数值
pDlg->Serializer->WriteString(passVehicle.license);
pDlg->Serializer->EndElement();
// 找到第4个参数
pDlg->Serializer->StartElement("s_hpzlmc","http://10.36.6.4/video/","","");
// 输入第4个参数值
char szVehicleType[16] = "";
switch (passVehicle.chCarShapeType)
{
case 1:
strcpy(szVehicleType,"小型汽车");
break;
case 2:
strcpy(szVehicleType, "大型汽车");
break;
default:
strcpy(szVehicleType,"无号牌");
break;
}
pDlg->Serializer->WriteString(szVehicleType);
pDlg->Serializer->EndElement();
// 找到第5个参数
pDlg->Serializer->StartElement("s_tgsj","http://10.36.6.4/video/","","");
// 输入第5个参数值
char szPassTime[20] = "";
COleDateTime passTime((time_t)passVehicle.dwPassTime);
sprintf(szPassTime,"%04d-%02d-%02d %02d:%02d:%02d",passTime.GetYear(),passTime.GetMonth(),passTime.GetDay(),passTime.GetHour(),passTime.GetMinute(),passTime.GetSecond());
pDlg->Serializer->WriteString(szPassTime);
pDlg->Serializer->EndElement();
// 找到第6个参数
pDlg->Serializer->StartElement("s_xsfx","http://10.36.6.4/video/","","");
// 输入第6个参数值
pDlg->Serializer->WriteString(passVehicle.chDriectName);
pDlg->Serializer->EndElement();
// 找到第7个参数
pDlg->Serializer->StartElement("s_cdh","http://10.36.6.4/video/","","");
// 输入第7个参数值
char szLane[20] = "";
sprintf(szLane,"道%d",passVehicle.dwLaneNum);
pDlg->Serializer->WriteString(szLane);
pDlg->Serializer->EndElement();
// 找到第8个参数
pDlg->Serializer->StartElement("s_xssd","http://10.36.6.4/video/","","");
// 输入第8个参数值
char szSpeed[5] = "";
sprintf(szSpeed,"%d",passVehicle.wCarSpeed);
pDlg->Serializer->WriteString(szSpeed);
pDlg->Serializer->EndElement();
// 找到第9个参数
pDlg->Serializer->StartElement("s_tplj","http://10.36.6.4/video/","","");
// 输入第9个参数值
pDlg->Serializer->WriteString(strcat(passVehicle.szJpegHttpPath,passVehicle.szJpegname));
pDlg->Serializer->EndElement();
pDlg->Serializer->EndElement();
pDlg->Serializer->EndBody();
pDlg->Serializer->EndEnvelope();
//将该消息发送给web服务
pDlg->Connector->EndMessage(); //将消息送往服务器
//将reader联接到connector的输出字符串
pDlg->Reader->Load(_variant_t((IUnknown*)pDlg->Connector->OutputStream), "");
//显示结果
//AfxMessageBox((const char *)Reader->Body->xml);//以xml格式输出
const char szResult[10]= "SUCCESS";
_bstr_t res = pDlg->Reader->RpcResult->text;
if(strcmp(szResult,res) != 0)
{
COleDateTime odtTime = COleDateTime::GetCurrentTime();
CString strTime = odtTime.Format();
CPowerInfo::Log("Info", strTime, "UploadByWebService上传数据失败!"+res);
}
else
{
COleDateTime odtTime = COleDateTime::GetCurrentTime();
CString strTime = odtTime.Format();
CPowerInfo::Log("Info", strTime, "UploadByWebService上传数据成功!");
}
pDlg->Connector.Release();
pDlg->Serializer.Release();
pDlg->Reader.Release();
}
catch (_com_error e)
{
COleDateTime odtTime = COleDateTime::GetCurrentTime();
CString strTime = odtTime.Format();
CString errormessage;
errormessage.Format("%s",e.Description());
CPowerInfo::Log("Info", strTime, "UploadByWebService上传数据失败!"+errormessage);
}
好了,总结一下必要的关键步骤:
1.导入类型库
2.需要创建一个SoapConnector
3.下一步创建SoapSerializer
4.下一步把消息附加到SoapConnector的输入流
5.下一步读取结果.要读取服务器的回复,客户端应用需要使用SoapReader,
6.SoapReader被连接到SoapConnector输出流
7.用IXMLDOMElement对象可以从SoapReader里读到服务器的回复
备注:注意使用的soapSDK的版本以及异常处理