понедельник, 4 января 2010 г.

POST запрос в QT с помощью QNetworkAccessManager

Переписывая первую версию функции для работы с Forismatic перешел к QNetworkAccessManager. В этом посте хочу написать как пользоваться этим классом, который значительно упростил отправку POST запроса в QT.

QNetworkAccessManager manager;
QNetworkReply *reply;
QUrl apiUrl;
QByteArray requestString;
QNetworkAccessManager - класс, для работы с сетью;
QNetworkReply - после запроса QNetworkAccessManager возвращает объект типа, который и будет содержать ответ от сервера;
QUrl - ссылка сайта, на который будем отправлять запрос;
QByteArray - параметры, которые будут переданы POST запросом;


Теперь непосредственно сам запрос, на примере, все того же forismatic.com
apiUrl = "http://www.forismatic.com/api/1.0/";
requestString = "method=getQuote&format=xml";
QNetworkRequest request(apiUrl);
reply = manager.post(request, requestString);
connect(reply, SIGNAL(finished()),this, SLOT(getReplyFinished()));
connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadReply()));
Здесь мы соединяем сигналы, которые получаем от QNetworkReply с соответствующими слотами, которые необходимj объявить в объявлении исходного класса.

В теле слота getReplyFinished() мы указываем что необходимо удалить обьект reply:
reply->deleteLater();

В теле слота readyReadReply() мы работаем с полученным ответом от сервера, для того чтобы его прочитать необходимо вызвать соответствующий метод:
QString answer = QString::fromUtf8(reply->readAll());
Так как ответ приходит в Utf8, То его необходимо расшифровать, поэтому используется QString::fromUtf8().

В данном примере я использовал сигнал readyRead() объекта QNetworkReply, хотя в данном случае можно было обойтись вообще без него, используя сигнал finished(QNetworkReply*) объекта QNetworkAccessManager. Сигнал readyRead() стоит использовать при достаточно больших ответах, размещение которых напрямую в памяти может быть накладно, и нужно, например, сохранять ответ в файл. Таким образом, весь POST запрос сокращается до нескольких строк:
QNetworkAccessManager * pManager = new QNetworkAccessManager;
connect(pManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinish(QNetworkReply*)));
pManager->post( QNetworkRequest(QUrl("http://api.forismatic.com/api/1.0/")), QString("method=getQuote&format=xml").toUtf8());

В заключении можно сказать, что QNetworkAccessManager обладает более гибким API, и позволяет значительно упростить работу с запросами. В следующей статье планируется написать про разбор простейшего xml файла с помощью QT и QXmlStreamReader.

Комментариев нет:

Отправить комментарий