12

I'm trying to get example found from this link to work.

GET and DELETE methods are working but I have some issue with PUT and POST. I get server replied: Bad Request. With qDebug() I get this error:

QNetworkReply::NetworkError(ProtocolInvalidOperationError)

To httprequestworker.cpp, I have changed request type to:

request_content.append("Content-Type: application/fhir+json");

Here is my function for getting contents of JSON file from computer and executing the whole input of request for the server:

void MainWindow::on_pushButton_clicked()
{
    QString url_str = "http://hapi.fhir.org/baseDstu3/Patient/4705560";

    HttpRequestInput input(url_str, "PUT");

    QString settings;
    QFile file;

    file.setFileName("C:/Users/Lauri/Desktop/FHIR/Omia testeja/themostsimplepatientJSON.json");
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    settings = file.readAll();
    file.close();

    settings.remove(QRegExp("[\\n]"));
    qDebug() << settings;
    settings.toUtf8();
    input.add_var("key1", settings);


    HttpRequestWorker *worker = new HttpRequestWorker(this);
    connect(worker, SIGNAL(on_execution_finished(HttpRequestWorker*)), this, SLOT(handle_result(HttpRequestWorker*)));
    worker->execute(&input);
}

Here is the simple JSON I want to upload:

{
  "resourceType": "Patient",
  "text": {
    "status": "generated",
    "div": "<div xmlns='http://www.w3.org/1999/xhtml'>This is a test patient<a name='mm'/></div>"
  },
  "name": [
    {
      "use": "usual",
      "prefix": [
        "Mr"
      ],
      "given": [
        "Teppo",
        "Testi"
      ],
      "family": "Testinen"
    }
  ],
  "telecom": [
    {
      "value": "123456789",
      "system": "phone",
      "use": "home"
    }
  ],
  "gender": "male",
  "birthDate": "2018-08-21"
}

JSON file should be right because I have been able to POST and PUT with postman and other tools. Is there something obvious that I'm missing?

Captures from postman:

PUT Headers

PUT Body

POST Headers

POST Body

With qDebug() I can see that reading JSON is successful. I have been trying to find solution for ProtocolInvalidOperationError with no success.

6
  • You could show how the petition does with postman. Commented Aug 13, 2018 at 7:55
  • Sorry but I'm not sure what You mean by petition. I added screenshot from postman to the post. Is that what You want need to see or something else? Commented Aug 13, 2018 at 8:35
  • Is that image from the POST request? Commented Aug 13, 2018 at 8:36
  • As I see the image is of the PUT, and of the POST? Commented Aug 13, 2018 at 8:38
  • I added body and headers for both PUT and POST from Postman Commented Aug 13, 2018 at 8:47

1 Answer 1

13

the class HttpRequestWorker does not support the sending of json, so I will not use it in the example. For this case I will use QNetworkAccessManager directly:

In the case of PUT you must add the id in the .json, so you can modify the file or do it by code, in this case use the second case:

PUT:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    void onManagerFinished(QNetworkReply *reply);

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager manager;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include <QNetworkReply>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(&manager, &QNetworkAccessManager::finished, this, &MainWindow::onManagerFinished);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    QNetworkRequest request(QUrl("http://hapi.fhir.org/baseDstu3/Patient/4705560"));
    request.setRawHeader("Content-Type", "application/fhir+json");
    QFile file("/path/of/themostsimplepatientJSON.json");
    if(file.open(QIODevice::ReadOnly)){
        QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
        QJsonObject obj = doc.object();
        obj["id"] = "4705560"; // add ID
        doc.setObject(obj);
        manager.put(request, doc.toJson());
    }
}

void MainWindow::onManagerFinished(QNetworkReply *reply)
{
    qDebug()<< reply->readAll();
}

output:

"{\n  \"resourceType\": \"OperationOutcome\",\n  \"text\": {\n    \"status\": \"generated\",\n    \"div\": \"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\"><h1>Operation Outcome</h1><table border=\\\"0\\\"><tr><td style=\\\"font-weight: bold;\\\">INFORMATION</td><td>[]</td><td><pre>Successfully created resource \\\"Patient/4705560/_history/7\\\" in 5ms</pre></td>\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t</tr>\\n\\t\\t\\t<tr>\\n\\t\\t\\t\\t<td style=\\\"font-weight: bold;\\\">INFORMATION</td>\\n\\t\\t\\t\\t<td>[]</td>\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t<td><pre>No issues detected during validation</pre></td>\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t</tr>\\n\\t\\t</table>\\n\\t</div>\"\n  },\n  \"issue\": [\n    {\n      \"severity\": \"information\",\n      \"code\": \"informational\",\n      \"diagnostics\": \"Successfully created resource \\\"Patient/4705560/_history/7\\\" in 5ms\"\n    },\n    {\n      \"severity\": \"information\",\n      \"code\": \"informational\",\n      \"diagnostics\": \"No issues detected during validation\"\n    }\n  ]\n}"

POST:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QMessageBox>
#include <QNetworkReply>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(&manager, &QNetworkAccessManager::finished, this, &MainWindow::onManagerFinished);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    QNetworkRequest request(QUrl("http://hapi.fhir.org/baseDstu3/Patient")); // without ID
    request.setRawHeader("Content-Type", "application/fhir+json");
    QFile file("/path/of/themostsimplepatientJSON.json");
    if(file.open(QIODevice::ReadOnly)){
        QByteArray ba = file.readAll();
        manager.post(request, ba);
    }
}

void MainWindow::onManagerFinished(QNetworkReply *reply)
{
    qDebug()<< reply->readAll();
}

output:

"{\n  \"resourceType\": \"OperationOutcome\",\n  \"text\": {\n    \"status\": \"generated\",\n    \"div\": \"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\"><h1>Operation Outcome</h1><table border=\\\"0\\\"><tr><td style=\\\"font-weight: bold;\\\">INFORMATION</td><td>[]</td><td><pre>Successfully created resource \\\"Patient/4728838/_history/1\\\" in 3ms</pre></td>\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t</tr>\\n\\t\\t\\t<tr>\\n\\t\\t\\t\\t<td style=\\\"font-weight: bold;\\\">INFORMATION</td>\\n\\t\\t\\t\\t<td>[]</td>\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t<td><pre>No issues detected during validation</pre></td>\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t</tr>\\n\\t\\t</table>\\n\\t</div>\"\n  },\n  \"issue\": [\n    {\n      \"severity\": \"information\",\n      \"code\": \"informational\",\n      \"diagnostics\": \"Successfully created resource \\\"Patient/4728838/_history/1\\\" in 3ms\"\n    },\n    {\n      \"severity\": \"information\",\n      \"code\": \"informational\",\n      \"diagnostics\": \"No issues detected during validation\"\n    }\n  ]\n}"

The complete example can be found in the following link

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a LOT for the help and great example eyllanesc!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.