- 今天搞定了Qt访问SOAP。
- 我用了最简单的方法:QNetworkAccessManager。代码如下:
#include <QGuiApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
int main(int argc, char *argv[])
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest req;
req.setUrl(QUrl("http://192.168.4.133:8080/services/TestDemo"));
req.setHeader(QNetworkRequest::ContentTypeHeader,("text/xml;charst=utf-8"));
QString soapXML = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:exam='http://example/'><soapenv:Header/><soapenv:Body><exam:test/></soapenv:Body></soapenv:Envelope>" ;
QNetworkReply *reply = manager->post(req,soapXML.toUtf8());
QAbstractSocket::connect(reply,&QNetworkReply::finished,[=](){
QString bytes =reply->readAll();
qDebug()<< bytes;
});
QGuiApplication app(argc, argv);
return app.exec();
}
返回结果:
总结:
- 刚开始,我没有加setHeader和XML值,返回的是测试地址的网页内容。
(可能懂C++的都不会犯下边这两个错误吧?抱歉我是个外行。) - 之后加上setHeader()和XML值之后报错,原因是我把soap的值分好几行写了,字符串之间用"+"连接。就报了这样的错误:
“invalid operands to binary expression ('const char * 'and 'const char *')”
- 另一个是单双引号的问题:
//正确的代码
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:exam='http://example/'>"
//错误的代码
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:exam="http://example/">'
新增读取值版本
参考链接:https://stackoverflow.com/questions/17346237/qt5-c-qbytearray-xml-parser
这个问答中包括了读取"标签值"和"属性值"两种方式。我需要用到的是读取标签值。
- 输入报文
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:malu="http://malu-robot.org">
<soapenv:Header/>
<soapenv:Body>
<malu:test/>
</soapenv:Body>
</soapenv:Envelope>
- 输出报文
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:testResponse xmlns:ns2="http://malu-robot.org">
<return>
<resultCode>200</resultCode>
<resultMessage>MaLu Soap-WebServices</resultMessage>
</return>
</ns2:testResponse>
</S:Body>
</S:Envelope>
我获取了<result></result>中的"resultCode"和"resultMessage"标签的值。
3.全部代码
#include <QGuiApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QXmlStreamReader>
#include <QJsonParseError>
#include <QtXml/QDomDocument>
#include <QtXml/qdom.h>
#include <QDebug>
int main(int argc, char *argv[])
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest req;
req.setUrl(QUrl("http://192.168.4.133:8080/services/TestDemo"));
req.setHeader(QNetworkRequest::ContentTypeHeader,("text/xml;charst=utf-8"));
QString soapXML = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:malu='http://malu-robot.org'><soapenv:Header/><soapenv:Body><malu:test/></soapenv:Body></soapenv:Envelope>" ;
QNetworkReply *reply = manager->post(req,soapXML.toUtf8());
QAbstractSocket::connect(reply,&QNetworkReply::finished,[=](){
QByteArray bytes = reply->readAll();
qDebug()<<bytes;
QXmlStreamReader reader(bytes);
while (!reader.atEnd())
{
if(reader.isStartElement())
{
if(reader.name() == "resultCode")
{
reader.readNext();
if(reader.atEnd())
{
break;
}
if(reader.isCharacters())
{
QString resultCode = reader.text().toString();
qDebug()<<resultCode;
}
}
if(reader.name() == "resultMessage")
{
reader.readNext();
if(reader.atEnd())
{
break;
}
if(reader.isCharacters())
{
QString resultMessage = reader.text().toString();
qDebug()<<resultMessage;
}
}
}
reader.readNext();
}
});
QGuiApplication app(argc, argv);
return app.exec();
}
题外话:
前几天,我在网上搜索到的方法看似有用的有几种,qtSoap非官方插件、gSoap等等,国内国外的经验几乎被我翻遍了,都没有找到行的通的例子。所以今天决定自己写,还真搞出来了。接下来该处理返回值了。
不建议小白去尝试qtSoap和gSoap,像我一样浪费几天时间一个都没搞定。如果有能力可以搞qtSoap。