Kun Qt-sovelluksessa halutaan käyttää HTTP-protokollaa, on projektiin lisättävä QtNetwork-moduuli seuraavasti:
qmake:
pro-tiedostoon
QT +=network
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets Network) PRIVATE Qt6::Network
QtNetwork on Qt-kirjaston moduuli, joka tarjoaa kehittäjille työkaluja verkko-ohjelmointiin ja verkkoyhteyksien hallintaan Qt-sovelluksissa. Moduuli sisältää muun muassa seuraavat luokat:
Luokka | Selite |
---|---|
QNetworkAccessManager | QNetworkAccessManager on QtNetwork-moduulin luokka, joka tarjoaa pääsyn verkkoresursseihin ja hallinnoi verkkopyyntöjä. Sen avulla voidaan helposti luoda ja käsitellä HTTP-pyyntöjä ja -vastauksia Qt-sovelluksissa. |
QNetworkRequest | QNetworkRequest on QtNetwork-moduulin luokka, joka edustaa HTTP- tai muuta verkko-pyyntöä. |
QNetworkReply | QNetworkReply on QtNetwork-moduulin luokka, josta luodun olion avulla päästään käsiksi http-response dataan. |
QJsonDocument | QJsonDocument on Qt:n luokka, jota käytetään JSON-objektien ja -taulukoiden (QJsonObject ja QJsonArray) lukemiseen ja kirjoittamiseen. |
QJsonArray | QJsonArray-luokan avulla voidaan käsitellä JSON-array-tyyppistä dataa. |
QJsonObject | QJsonObject luokan avulla voidaan käsitellä JSON-object tyyppistä dataa. |
HTTP-responsen data luetaan tämän sivun esimerkeissä QByteArray-luokan olioon.
QString site_url="http://localhost:3000/book"; QNetworkRequest request(site_url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); manager = new QNetworkAccessManager(this); connect(manager, &QNetworkAccessManager::finished, this, &CurrentClassName::getBookSlot); reply = manager->get(request);Kun HTTP response saapuu, QNetworkAccessManager emittoi finished signaalin, joka on edellä kytketty getBookSlot-slottiin.
QString site_url="http://localhost:3000/book"; QNetworkRequest request(site_url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); //WEBTOKEN ALKU //Onnistuneen loginin seurauksena saadaan arvo muuttujalle webToken, jonka //tietotyyppi on QByteArray ja sen eteen asetetaan merkkijono Bearer QByteArray myToken="Bearer "+webToken; request.setRawHeader(QByteArray("Authorization"),(myToken)); //WEBTOKEN LOPPU manager = new QNetworkAccessManager(this); connect(manager, &QNetworkAccessManager::finished, this, &CurrentClassName::getBookSlot); reply = manager->get(request);Huom! Varsinaisen tokenin (eli webToken) eteen on siis kirjoitettava sana Bearer.
Edellä siis tehtiin http-request ja finished-signaali kytkettiin slottiin getBookSlot. Nyt siis response käsitellään tuossa slotissa.
void MainWindow::getBookSlot (QNetworkReply *reply) { QByteArray response_data=reply->readAll(); // Muunnetaan vastaus QByteArray-tyyppisestä JSON-dokumentiksi QJsonDocument json_doc = QJsonDocument::fromJson(response_data); // Muunnetaan JSON-dokumentti JSON-objektiksi QJsonObject json_obj = json_doc.object(); // Käsitellään JSON-objektia reply->deleteLater(); manager->deleteLater(); }
void MainWindow::getBookSlot (QNetworkReply *reply) { QByteArray response_data=reply->readAll(); // Muunnetaan vastaus QByteArray-tyyppisestä JSON-dokumentiksi QJsonDocument json_doc = QJsonDocument::fromJson(response_data); // Muunnetaan JSON-dokumentti JSON-arrayksi QJsonArray json_array = json_doc.array(); // Käsitellään JSON-arraytä reply->deleteLater(); manager->deleteLater(); }
fromJson metodia, voidaan kutsua myös antamalla QJsonParseError-viite seuraavasti:
QJsonParseError parseError; QJsonDocument json_doc = QJsonDocument::fromJson(response_data, &parseError);Silloin voidaan tarkistaa tapahtuiko virhe seuraavasti:
if (parseError.error != QJsonParseError::NoError) { qWarning() << "JSON parsing error:" << parseError.errorString(); // Tässä vaiheessa json_doc ei ole kelvollinen }
JSON-objektin kenttiin päästään käsiksi seuraavasti:
int book_id = json_obj["id_book"].toInt(); QString book_name = json_obj["name"].toString();
JSON-array:tä voidaan käsitellä seuraavalla foreach-loopilla:
foreach (const QJsonValue &value, json_array) { // Toimenpiteet }
Jos haluat päästä käsiksi JSON-arrayn yksittäisen objektin kenttään, voit käyttää seuraavaa rakennetta
QString book_name = json_array.at(0)["name"].toString();Edellä QStringiin nimeltään book_name sijoitetaan ensimmäisen objektin (at(0)) name kentän arvo.
Käytännössä JSON-data kannattaa usein mäpätä C++-olioiksi, jolloin sitä on helpompi käsitellä. Esimerkiksi edellisten esimerkkien tapauksessa voisi luoda Book-luokan seuraavilla koodeilla:
#ifndef BOOK_H #define BOOK_H #include <qjsonobject.h> class Book { public: int id; QString name; QString author; static Book mapJson(const QJsonObject &json); }; #endif // BOOK_H
#include "book.h" Book Book::mapJson(const QJsonObject &json) { Book book; book.id = json["id_book"].toInt(); book.name = json["name"].toString(); book.author = json["author"].toString(); return book; }
Jos http-responsena saadaan JSON-objekti voidaan luoda Book-luokan olio seuraavasti:
Book book = Book::mapJson(json_obj);
Jos http-responsena saadaan json array voidaan luoda Book-olioita sisältävä QVector seuraavasti:
QVector<Book> bookList; for (const QJsonValue &value : json_array) { if (value.isObject()) { Book book = Book::mapJson(value.toObject()); bookList.append(book); } }
Edellä metodi mapJson määriteltiin staattiseksi, jotta: