Qt-ohjelmointi
Qt HTTP

Kun Qt-sovelluksesta halutaan lähettää HTTP-requesteja palvelimelle, joka vastaa JSON-muodossa, lisätään sovellukseen seuraavat:

  1. pro-tiedostoon rivi
    QT +=network
    
  2. h-tiedostoon rivit
    #include <QtNetwork>
    #include <QNetworkAccessManager>
    #include <QJsonDocument>
    

QtNetwork
QtNetwork on Qt-kirjaston moduuli, joka tarjoaa kehittäjille työkaluja verkko-ohjelmointiin ja verkkoliitäntöjen hallintaan Qt-sovelluksissa.
QNetworkAccessManager
QNetworkAccessManager on QtNetwork-moduulin luokka, joka tarjoaa pääsyn verkkoresursseihin ja hallinnoi verkkopyyntöjä. Se tarjoaa yksinkertaisen tavan luoda ja hallita HTTP-pyyntöjä ja vastauksia Qt-sovelluksissa.
QNetworkReply
QNetworkReply on QtNetwork-moduulin luokka, josta luodun olion avulla päästään käsiksi http-response dataan.
QByteArray
QByteArray on Qt:n luokka, joka tarjoaa dynaamisen tavujonon eli tavupuskurin. HTTP-response data voidaan lukea QByteArray olioon (alla nimeltään response_data) seuraavasti:
QByteArray response_data=reply->readAll();
QJsonDocument
QJsonDocument on luokka, jonka avulla voidaan lukea ja kirjoittaa JSON dokumentteja (Array ja Object).
QJsonArray
QJsonArray luokan avulla voidaan käsitellä JSON-array muotoista dataa.
QJsonObject
QJsonObject luokan avulla voidaan käsitellä JSON-object muotoista dataa.
HTTP GET esimerkki
HTTP liikenne toimii asynkronisesti, joten käytetään Signal-Slot systeemiä. Alla lähetetään HTTP GET metodilla request
Ei autentikointia
QString site_url="http://localhost:3000/book";
QNetworkRequest request((site_url));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished (QNetworkReply*)),this, SLOT(getBookSlot(QNetworkReply*)));
reply = manager->get(request);
Webtoken autentikointi
Edellinen esimerkki, jos API vaatii webtokenia
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, SIGNAL(finished (QNetworkReply*)),this, SLOT(getBookSlot(QNetworkReply*)));
reply = manager->get(request);
Huom! Varsinaisen tokenin (eli webToken) eteen on siis kirjoitettava sana Bearer.
Http responsen käsittely

Edellä siis tehtiin http-request ja signaali kytkettiin slottiin getBookSlot. Nyt siis response käsitellään tuossa slotissa.

Responsena JSON-array
Oletetaan että edelliseen http pyyntöön saadaan vastaus JSON-array muodossa ja tulokset halutaan tulostaa textEditResults nimiseen TextEdit objektiin. JSON-array:n objektit voidaan käsitellä foreach-loopilla seuraavasti:
void MainWindow::getBookSlot (QNetworkReply *reply)
{
    QByteArray response_data=reply->readAll();
    QJsonDocument json_doc = QJsonDocument::fromJson(response_data);
    QJsonArray json_array = json_doc.array();
    QString book;
    foreach (const QJsonValue &value, json_array) {
        QJsonObject json_obj = value.toObject();
        book+=QString::number(json_obj["id_book"].toInt())+","+json_obj["name"].toString()+","+jsonobj["author"].toString()+"\r";
    }

    qDebug()<<book;

    ui->textEditResults->setText(book);

    reply->deleteLater();
    manager->deleteLater();
}    

Jos haluat päästä käsiksi JSON-arrayn yksittäisen objektin kenttään, voit käyttää seuraavaa rakennetta

QByteArray response_data=reply->readAll();
QJsonDocument json_doc = QJsonDocument::fromJson(response_data);
QJsonArray json_array = json_doc.array();
QString author=json_array.at(0)["author"].toString();
Edellä QStringiin nimeltään author sijoitetaan ensimmäisen objektin (at(0)) author kentän arvo.

Responsena JSON-objekti
Mikäli edellä esitetty HTTP response sisältäisi JSON objektin voitaisiin se käsitellä seuraavalla koodilla.
void MainWindow::getBookSlot (QNetworkReply *reply)
{
    QByteArray response_data=reply->readAll();
    QJsonDocument json_doc = QJsonDocument::fromJson(response_data);
    QJsonObject json_obj = json_doc.object();
    QString book;
    book=QString::number(json_obj["id_book"].toInt())+","+json_obj["name"].toString()+","+json_obj["author"].toString();
    
    qDebug()<<book;
    
    ui->textEditResults->setText(book);
    
    reply->deleteLater();
    manager->deleteLater();
}
deleteLater
deleteLater()-metodia käytetään yleensä Qt-sovelluksissa tilanteissa, joissa halutaan poistaa dynaamisesti luotu olio turvallisesti. Tämä metodi asettaa olion poistettavaksi myöhemmin Qt:n tapahtumakäsittelyjärjestelmän kautta, mikä varmistaa, että olio poistetaan oikeassa kohtaa ohjelman suoritusjärjestystä. Tämä on erityisen tärkeää, jos olio on sidottu muihin osiin ohjelmaa, kuten signaaleihin.
Yhteenveto

Http-request siis tehdään jostain funktiosta (vaikka buttonin klikkaus). Tuossa funktiossa signaali (finished) kytketään slottiin, jossa http-response(reply) käsitellään.