RESTful API 使用 Qt 的请求
RESTful API requests using Qt
我正在尝试让从这个 link 中找到的示例起作用。
GET
和 DELETE
方法有效,但我对 PUT
和 POST
有一些问题。我收到服务器回复:错误请求。使用 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 文件应该是正确的,因为我已经能够 POST
和 PUT
使用邮递员和其他工具。有什么明显的我遗漏的东西吗?
来自邮递员的截图:
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
我正在尝试让从这个 link 中找到的示例起作用。
GET
和 DELETE
方法有效,但我对 PUT
和 POST
有一些问题。我收到服务器回复:错误请求。使用 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 文件应该是正确的,因为我已经能够 POST
和 PUT
使用邮递员和其他工具。有什么明显的我遗漏的东西吗?
来自邮递员的截图:
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