gsoap入门:解决axis2服务器返回错误:com.ctc.wstx.exc.WstxParsi
我们的项目中webservice服务器已经搭建好,基于用axis2提供名为FaceDbService的人脸识别服务。现在的任务是用gosap开发C++版本的客户端,所以最近在尝试用gsoap生成的c++代码来调用webservice.
测试代码下面是测试代码 #include <sstream>
#include "FaceDbServiceSoap11Binding.nsmap"
#include "file_utilits.h"
#include "stdlib.h"
#include "plugin.h"
using namespace facedbservice;
int main(int argc,char * argv[]) {
struct soap soap;
// 对象初始化
soap_init(&soap);
// 注册plugin插件,用于显示request/response xml文本用于调试
soap_register_plugin(&soap,plugin);
// RPC调用参数对象
_ns1__sdk_USCOREdetectFace param;
// RPC返回对象
_ns1__sdk_USCOREdetectFaceResponse ret;
// 加载一张图像数据到内存(字节数组std::vector<uint8_t>)
auto img_file= gdface::load_binary_file("d:tmphe049.jpg");
// 将字节数组转为xsd__base64Binary对象,并设置为imgData参数
xsd__base64Binary b;
b.soap = &soap;
b.__ptr = img_file.data();
b.__size = img_file.size();
param.imgData = &b;
// 执行soap调用detectFace
soap_call___ns1__sdk_USCOREdetectFace(&soap,"http://gdface.wicp.net:15865/axis2/services/FaceDbService",nullptr,¶m,ret);
// 检查错误
if (soap.error!= SOAP_OK) {
// 显示错误信息
soap_stream_fault(&soap,std::cerr);
}else {
// 调用成功则输出返回的数据
for (auto code : ret.return_) {
std::printf("soap err,errcode = (%d,%d,%d)n",*(code->pos->left),*(code->pos->top),*(code->pos->width),*(code->pos->height));
}
}
soap_done(&soap);
}
错误信息程序执行时出错了: /////////plugin插件输出的 request xml///////////////////////////////////
POST /axis2/services/FaceDbService HTTP/1.1
Host: 192.168.1.18:8080
User-Agent: gSOAP/2.8
Content-Type: text/xml; charset=utf-8
Content-Length: 8583
Connection: close
SOAPAction: "urn:sdk_detectFace"
<?xml version="1.0" encoding="UTF-8"?>
<ns:sdk_detectFace><ns:imgData>
//...图像数据
</ns:imgData></ns:sdk_detectFace>
HTTP/1.1 500 Int
ernal Server Error
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Sat,13 Aug 2016 02:55:08 GMT
Connection: close
/////////plugin插件输出的 response xml///////////////////////////////////
205
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://sc hemas.xmlsoap.org/soap/envelope/"><soapenv:Header xmlns:wsa="http://www.w3.org/2 005/08/addressing"><wsa:Action>http://www.w3.org/2005/08/addressing/soap/fault</ wsa:Action></soapenv:Header><soapenv:Body><soapenv:Fault><faultcode></faultcode>
<faultstring>com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix
"ns1"
at [row,col {unknown-source}]: [2,19]</faultstring><detail /></soapenv:Fault></ soapenv:Body></soapenv:Envelope>
///////// 上面代码中soap_stream_fault()输出///////
Error 500 fault at source[no subcode]
"Error 500: HTTP 500 Internal Server Error"
Detail: [no detail]
原因分析总是返回 其中一个答案,给了我提醒 : 貌似是因为soap.namespaces变量为NULL造成的,再运行程序证实了这个猜测,soap.namespaces果然为NULL; 于是尝试在soap对象创建后,添加如下代码,问题解决。 if(!soap->namespaces)
soap->namespaces=namespaces;
// namespaces变量定义在#include "FaceDbServiceSoap11Binding.nsmap"
解决方案虽然这样解决了问题,但还是不知道为什么呀,网上其他的教程中没有提到要手工设置 因为我在用gsoapcpp2生成gosap C++客户端代码的时候使用了 再进一步研究gsoap的手册关于编译参数的控制参见《9.11 Library Build Flags》,找到 这里说明,如果使用了 到此,问题基本算是搞清楚了,导致soap请求数据格式错误的直接原因是soap初始化时没有指定namespace。 从上面的分析来看,解决这个问题,有两个方案: 解决方案1去掉编译 解决方案2在soap对象初始化后用 #include <sstream>
#include "FaceDbServiceSoap11Binding.nsmap"
#include "file_utilits.h"
#include "stdlib.h"
#include "plugin.h"
using namespace facedbservice;
int main(int argc,char * argv[]) {
soap soap;
// 对象初始化
// soap_init(&soap);//C++下不需要,因为soap的构造函数已经执行过soap_init
// 设置namespaces
// namespaces变量定义在#include "FaceDbServiceSoap11Binding.nsmap"
soap_set_namespaces(&soap,namespaces);
// 下面省略的代码与以前相同
.....
//soap_done(&soap);//C++下不需要,因为soap的析构函数会执行soap_done
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |