RESTful API 使用 Qt 的请求

RESTful API requests using Qt

我正在尝试让从这个 link 中找到的示例起作用。

GETDELETE 方法有效,但我对 PUTPOST 有一些问题。我收到服务器回复:错误请求。使用 qDebug() 我得到这个错误:

QNetworkReply::NetworkError(ProtocolInvalidOperationError)

httprequestworker.cpp,我已将请求类型更改为:

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

这是我从计算机获取 JSON 文件内容并执行服务器请求的整个输入的函数:

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);
}

这里是我要上传的简单JSON:

{
  "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 文件应该是正确的,因为我已经能够 POSTPUT 使用邮递员和其他工具。有什么明显的我遗漏的东西吗?

来自邮递员的截图:

POST Headers

POST Body

qDebug()可以看出读取JSON成功了。我一直在尝试为 ProtocolInvalidOperationError 寻找解决方案,但没有成功。

classHttpRequestWorker不支持发送json,所以例子中就不使用了。对于这种情况,我将直接使用 QNetworkAccessManager

在PUT的情况下你必须在.json中添加id,所以你可以修改文件或通过代码来完成,本例使用第二种情况:

放置:

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();
}

输出:

"{\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();
}

输出:

"{\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}"

完整的例子可以在下面找到link