Rest client with Qt 4.5
It’s very easy to call a rest service from qt, even with authentication,
using QtNetwork/QNetworkAccessManager class
http://doc.trolltech.com/4.5/qnetworkaccessmanager.html.
Using the previous rest servlet sample.
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QObject::connect(manager, SIGNAL(finished(QNetworkReply *)),
SLOT(slotRequestFinished(QNetworkReply *)));
QNetworkRequest request;
request.setUrl(QUrl("http://localhost:8080/restservlet/sample/tommy"));
request.setRawHeader("Authorization", "Basic " +
QByteArray(QString("%1:%2").arg("user").arg("asas").toAscii()).toBase64());
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/xml");
QNetworkReply *reply = 0;
reply = manager->get(request);
QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
SLOT(slotProgress(qint64,qint64)));
void SampleRestClient::slotRequestFinished(QNetworkReply *reply)
{
if (reply->error() > 0) {
qDebug() <errorString();
}
else {
QDomDocument doc;
QXmlInputSource is;
is.setData(reply->readAll());
doc.setContent(is.data());
QDomNodeList nodes = doc.elementsByTagName("message");
if (nodes.size() > 0) {
qDebug() << nodes.at(0).toElement ().text ();
}
}
}
-
We neet to set the Authorization header for the basic http auth mechanism.
Just “Basic user:password” user and password encoded with base64. - We can use QDomDocument to get the xml representation of the rest response.
Here is the complete code sample :
- main.cpp
#include "mainwindow.h" #include <QtGui/QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } -
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui/QWidget> class QLabel; class QProgressBar; class QNetworkAccessManager; class QNetworkReply; class MainWindow : public QWidget { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void slotRequestFinished(QNetworkReply *); void slotSetProgress(qint64, qint64); private: QLabel *m_label; QProgressBar *m_progress; QNetworkAccessManager *m_network; }; #endif // MAINWINDOW_H -
mainwindow.cpp
#include "mainwindow.h" #include <QDebug> #include <QThread> #include <QtCore/QUrl> #include <QtGui/QLabel> #include <QtGui/QProgressBar> #include <QtGui/QVBoxLayout> #include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkProxy> #include <QtXml/QDomDocument> static const char *REQUEST_URL = "http://localhost:8080/restservlet/rest/sample/tommy"; static const char *USER = "user"; static const char *PASSWORD = "asas"; MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); m_label = new QLabel(); m_progress = new QProgressBar(); m_progress->setRange(0, 100); layout->addWidget(m_label); layout->addWidget(m_progress); setLayout(layout); m_network = new QNetworkAccessManager(this); QNetworkRequest request; request.setRawHeader("Authorization", "Basic " + QByteArray(QString("%1:%2").arg(USER).arg(PASSWORD).toAscii()).toBase64()); request.setUrl(QUrl(REQUEST_URL)); QNetworkReply *reply = m_network->get(request); QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(slotSetProgress(qint64,qint64))); QObject::connect(m_network, SIGNAL(finished(QNetworkReply *)), SLOT(slotRequestFinished(QNetworkReply *))); } MainWindow::~MainWindow() { } void MainWindow::slotRequestFinished(QNetworkReply *reply) { m_progress->setValue(0); if (reply->error() > 0) { m_label->setText("Error number = " + reply->errorString()); } else { QByteArray data = reply->readAll(); QDomDocument doc; doc.setContent(data); QDomNodeList nodes = doc.elementsByTagName("message"); if (nodes.size() > 0) { m_label->setText(nodes.at(0).toElement().text()); } } } void MainWindow::slotSetProgress(qint64 received, qint64 total) { if (total > 0 && received > 0) { m_progress->setValue((int) total / received); } } -
sample.pro
QT += network xml TARGET = sample_rest_client TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h - qmake && make && ./sample_rest_client to try it!

My friend,
Thanks for this sample. You really helped me a lot!! š
Thanks again!
Wow, this looks really amazing. Was searching for this everywhere and finally found it. Will try it out and let you now. Thanks a ton!!!
Hi any idea of how to get attributes with a tag/element like content, using the above I can only extract “content” in the node list, any pointers on how i can extract “name” or “alpha” or “name=alpha”?
Maybe i’m misinterpreting your question, but you can always get the node attributes
nodes.at(0).toElement().attribute(“name”, “defaultValue”);
http://doc.trolltech.com/4.6/qdomelement.html#attributex
Hope it helps š
Thanks a lot, this sample really cleared a lot of things for me š
I’ve been trying to get this example to work synchronously using the 4.7 preview. In the constructor of MainWindow before the connections are made, I put the following calls:
reply->waitForReadyRead(-1);
QByteArray data = reply->readAll();
QString dataStr(data);
qDebug() << "received response synchronously <" << dataStr <“;
According to the Qt documentation this should block until the response arrives, but it returns immediately and prints out an empty string as its response. Does anyone have an idea why this might be? Am I doing something wrong, or is this a bug in the 4.7 preview?
hi,
I cannot make it work ( waitForReadyRead(-1) ) with 4.6 neither,
but a simple way of doing that would be using QEventLoop
Here’s a sample http://github.com/jgoday/sample_sync_network
waitForReadyRead() is not reimplemented in QNetworkReply, the default implementation of QIODevice::waitForReadyRead() does nothing, and returns false.
You might need to deleteLater the reply in the slotRequestFinished.
Appreciating the commitment you put into your website and in depth information you offer.
It’s good to come across a blog every once in a while that isn’t the same outdated rehashed material.
Great read! I’ve bookmarked your site and I’m including
your RSS feeds to my Google account.
Hi there just wanted to give you a quick heads up.
The words in your content seem to be running off the screen in Firefox.
I’m not sure if this is a formatting issue or something to do with internet browser compatibility but I figured I’d post to let you know.
The layout look great though! Hope you get the problem solved soon.
Thanks
Heya i am for the primary time here. I came across this board and I
to find It truly helpful & it helped me out a lot.
I hope to present something back and aid others such
as you helped me.