文章目錄
- 軟件開發網絡架構
- BS架構/CS架構
- HTTP基本概念
- QT的HTTP編程
- JSON數據
- 概述
- QT生成JSON數據
- QT解析JSON數據
軟件開發網絡架構
BS架構/CS架構
? 在計算機網絡和軟件開發中,CS架構(Client-Server Architecture,客戶端-服務器架構)和BS架構(Browser-Server Architecture,瀏覽器-服務器架構)是兩種主要的應用程序架構。
? CS架構是一種典型的兩層結構,包括客戶端和服務器兩個部分。在這種架構中,客戶端和服務器通過網絡進行通信,每部分都有明確的職責。
- 客戶端:
-
用戶界面通常在客戶端呈現。
-
可以是桌面應用程序、移動應用或專用軟件。
-
負責向服務器發送請求,接收和處理服務器響應。
- 服務器:
-
管理數據和業務邏輯。
-
處理來自客戶端的請求,并發送回響應。
-
通常承載在遠程系統上,如數據庫服務器、應用服務器等。
- 特點:
-
需要為每種操作系統或平臺單獨開發客戶端。
-
高效的數據處理和響應能力。
-
在客戶端設備上占用資源(如內存和處理能力)。
BS架構(瀏覽器-服務器架構)
BS架構是一種基于Web的層或多層架構,主要通過Web瀏覽器作為客戶端訪問服務器上的應用程序。
- 瀏覽器(客戶端):
-
使用標準Web瀏覽器(如Chrome、Firefox等)作為客戶端。
-
無需安裝額外的軟件,使用HTML、CSS和JavaScript顯示內容。
- 服務器:
-
和CS架構中的服務器類似,處理業務邏輯和數據存儲。
-
通過Web服務(如HTTP服務器)提供頁面和數據。
- 特點:
-
跨平臺兼容性強,可以在任何支持Web瀏覽器的設備上運行。
-
客戶端無需安裝專用軟件,容易維護和更新。
-
可能依賴網絡性能,因為所有操作都在服務器上進行。
對比
-
部署和維護:BS架構易于部署和維護,而CS架構通常需要在每個客戶端單獨安裝和更新。
-
性能:CS架構可以更有效地利用客戶端的計算資源,適合高性能要求的應用。BS架構依賴于服務器的性能和網絡延遲。
-
安全性:CS架構中,數據經常在客戶端和服務器之間傳輸,可能需要更復雜的安全措施。BS架構中,敏感數據主要存儲在服務器端。
-
用戶體驗:CS架構通常能提供更豐富的用戶界面和交互功能。BS架構的用戶體驗受限于Web技術的能力。
在實際應用中,選擇哪種架構取決于具體的業務需求、目標用戶群、性能要求以及開發和維護的成本。
HTTP基本概念
HTTP(超文本傳輸協議)是一種用于分布式、協作式和超媒體信息系統的應用層協議。它是萬維網(WWW)的數據通信的基礎。了解HTTP的基本概念對于理解現代網絡通信至關重要。以下是HTTP的一些核心概念:
1. 請求和響應
HTTP是一個基于請求-響應模式的協議。客戶端(通常是Web**瀏覽器)向服務器發送一個HTTP請求,然后服務器返回一個HTTP響應。**請求包含請求的資源(如網頁),而響應包含請求的資源的內容。
- HTTP方法
HTTP定義了一系列的方法來表明對資源的不同操作,最常用的包括:
-
GET: 用于請求資源。
-
POST: 用于提交數據給服務器(例如,表單數據)。
-
PUT: 用于上傳文件或內容。
-
DELETE: 用于請求刪除資源。
-
HEAD: 用于獲取資源的元信息,而不是資源本身。
3. 狀態碼
服務器對請求的響應中包含一個狀態碼,它表示請求的成功或失敗,以及失敗的原因。常見的狀態碼包括:
-
200 OK: 請求成功。
-
404 Not Found: 請求的資源未找到。
-
500 Internal Server Error: 服務器內部錯誤。
-
301 Moved Permanently: 請求的資源已永久移動到新位置。
4. URL**(統一資源定位符)**
URL是Web上資源的地址。它指定了資源的位置以及用于訪問資源的協議(例如,http://)。
- HTTP頭
HTTP請求和響應包含頭部信息,這些信息包括元數據,如內容類型、內容長度、服務器信息、客戶端信息等。例如, Content-Type 頭部指示響應中的媒體類型(如text/html,application/json)。
6. 無狀態協議
HTTP是一個無狀態協議,這意味著服務器不會保留任何請求的數據(狀態)。然而,通過使用如Cookies這樣的機制,可以在多個請求之間維持狀態。
7. **安全性(**HTTPS)
HTTPS是HTTP的安全版本,它在HTTP和TCP層之間增加了一個加密層(通常是SSL/TLS)。這提供了數據傳輸的加密和更好的安全性。
8. RESTful API
RESTful是一種使用HTTP協議的Web服務設計風格,它利用HTTP的方法來實現API的不同操作。在
RESTful架構中,每個URL代表一個資源,并使用HTTP的方法(如GET, POST)來處理這些資源。
9. Session和Cookies
由于HTTP本身是無狀態的,Cookies和會話(Session)被用來在多個請求之間存儲用戶數據,從而為用戶提供連貫的體驗。
這些概念構成了HTTP的基礎,是理解和使用HTTP協議的關鍵。每個概念都有它的具體細節和使用場景,了解這些有助于更好地在網絡應用開發中應用HTTP。
QT的HTTP編程
Qt中的HTTP編程主要涉及使用Qt的網絡模塊來進行HTTP請求和處理HTTP響應。Qt提供了一系列類來處理網絡通信,其中最常用的類是 QNetworkAccessManager
、 QNetworkRequest
、QNetworkReply
以及相關的支持類。
以下是一個基本的HTTP編程示例,展示了如何使用Qt發送一個簡單的HTTP GET請求并處理響應:
步驟 1: 包含必要的頭文件
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QObject>
#include <QDebug>
步驟 2: 發送HTTP請求
創建一個 QNetworkAccessManager
對象,并使用它發送HTTP請求。 QNetworkAccessManager
對象會異步地處理請求,并返回一個 QNetworkReply 對象
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QNetworkAccessManager manager;QNetworkRequest request(QUrl("http://example.com"));QNetworkReply *reply = manager.get(request);QObject::connect(reply, &QNetworkReply::finished, [&]() {if (reply->error()) {qDebug() << "Error:" << reply->errorString();return;}QString response = reply->readAll();qDebug() << "Response:" << response;});return a.exec();
}
? 在這個例子中,我們使用 QNetworkAccessManager 的 get 方法發送了一個HTTP GET請求到"http://example.com"。然后,我們連接了 QNetworkReply 對象的 finished 信號到一個lambda函數,該函數在收到HTTP響應時被調用。
注意事項
-
異步處理: QNetworkAccessManager 的請求是異步的。這意味著 get 方法會立即返回,而HTTP響應將在稍后通過信號處理。
-
錯誤處理: 應該檢查 QNetworkReply 對象是否有錯誤,并相應地處理。
-
內存管理: QNetworkReply 對象需要被正確地管理,以避免內存泄漏。通常情況下,使用QObject::deleteLater 來安排刪除它是一個好方法。
JSON數據
概述
==JSON(JavaScript Object Notation)==是一種輕量級的數據交換格式。它易于人閱讀和編寫,同時也易于機器解析和生成。JSON是基于JavaScript的一個子集,盡管它是獨立于語言的,且有多種語言支持。JSON常用于網絡應用程序中的數據傳輸,尤其是在Web應用程序中與后端服務器通信。
使用JSON的原因總結如下:
原因 | 描述 |
---|---|
易于閱讀和編寫 | JSON的結構簡單、清晰,對人類來說易于閱讀和編寫。 |
輕量級數據格式 | 相較于XML等標記語言,JSON更輕量,使用更少的符號,數據體積更小。 |
易于解析和生成 | 大多數編程語言都提供了解析和生成JSON的內置支持或庫。 |
跨語言支持 | JSON是獨立于語言的,被廣泛支持和使用在多種編程語言中。 |
BS/CS開發過程中,會使用不同的編程語言,JSON作為數據傳輸的標準化格式,方便程序員協議約定和數據處理,以下是不同編程語言處理JSON的方案
語言/平臺 | JSON處理庫/接口 | 特點/描述 |
---|---|---|
C | Jansson | 提供JSON的編碼、解碼和處理功能 |
C++ | nlohmann/json | 現代C++(從C++11開始)的JSON庫,易于使用 |
Java | Jackson | 強大的JSON處理庫,支持JSON的序列化和反序列化 |
Python | json | Python標準庫中的JSON處理模塊 |
Qt | QJsonDocument | Qt框架中用于JSON處理的類 |
Android | org.json | Android SDK自帶的JSON處理類,提供基礎JSON操作功能 |
QT生成JSON數據
在Qt中生成JSON數據并將其保存到文件的一個基本示例涉及使用 QJsonDocument
、 QJsonObject
和QJsonArray
類。以下是創建一個簡單JSON對象并將其保存到文件的示例代碼。
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QDebug>
void createJsonFile() {// 創建一個JSON對象 鍵值對QJsonObject jsonObj;jsonObj["name"] = "John Doe";jsonObj["age"] = 30;jsonObj["email"] = "john.doe@example.com";// 創建一個JSON數組QJsonArray jsonArr;jsonArr.append("C++");jsonArr.append("Python");jsonArr.append("JavaScript");jsonArr.append(123);// 將數組添加到JSON對象jsonObj["languages"] = jsonArr;// 將JSON對象轉換為JSON文檔QJsonDocument jsonDoc(jsonObj);// 將JSON文檔轉換為字符串(也可以是壓縮格式)QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);// 將JSON數據寫入文件QFile file("output.json");if (!file.open(QIODevice::WriteOnly)) {qDebug() << "Failed to open file for writing";return;}file.write(jsonData);file.close();qDebug() << "JSON data saved to output.json";
}
int main() {createJsonFile();return 0;
}
說明
- 創建JSON對象:使用 QJsonObject 來構建JSON對象,并使用鍵值對填充數據。
- 創建JSON數組**:使用 QJsonArray 來創建一個數組,并添加元素。
- 組合JSON結構:將JSON數組添加到JSON對象中。
- 生成JSON文檔:通過 QJsonDocument 來處理JSON數據,可以選擇格式化(縮進)或壓縮形式。
- 保存到文件:創建 QFile 對象,打開文件,寫入JSON數據,并關閉文件。
這個例子展示了Qt中處理JSON的基礎流程,包括創建、填充數據、轉換為字符串,以及寫入文件。您可以根據需要調整這個流程來適應更復雜的JSON結構或數據。
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);QJsonObject rootObj;rootObj["cityid"] = "1010100";rootObj["date"] = "2024-01-23";rootObj["weather"] = "雨夾雪";rootObj["tmp"] = 3;QJsonArray jsonArray;jsonArray.append("data1");jsonArray.append("data2");jsonArray.append("data3");jsonArray.append(100);rootObj["testArry"] = jsonArray;QJsonDocument jsonDoc(rootObj);QByteArray jsonArry = jsonDoc.toJson();QFile file("D:/QT/test.json");file.open(QIODevice::WriteOnly);file.write(jsonArry);file.close();}
Widget::~Widget()
{delete ui;
}
? 在JSON中,數組可以包含多種類型的元素,包括對象。當您在Qt中處理JSON數組,其中的元素是對象時,您可以使用 QJsonArray 和 QJsonObject 來創建和處理這些數據結構。以下是一個示例,展示了如何創建一個包含多個對象的JSON數組,并將該數組添加到一個JSON對象中。
示例:
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);QJsonObject rootObj;rootObj["cityid"] = "1010100";rootObj["date"] = "2024-01-23";rootObj["weather"] = "雨夾雪";rootObj["tmp"] = 3;//Json數組QJsonArray jsonArray;jsonArray.append("data1");jsonArray.append("data2");jsonArray.append("data3");jsonArray.append(100);rootObj["testArry"] = jsonArray;QJsonObject alarmObj;alarmObj["alamType"] = "雪災";alarmObj["alamLeve"] = "黃色";alarmObj["alamTitle"] = "福州市警告老陳多穿點衣服";rootObj["alam"] = alarmObj;QJsonObject day0;day0["day"] = "星期一";day0["wea"] = "晴";day0["tem"] = 5.7;QJsonObject day1;day1["day"] = "星期二";day1["wea"] = "晴";day1["tem"] = 7;QJsonObject day2;day2["day"] = "星期三";day2["wea"] = "多云";day2["tem"] = 17;QJsonArray dayArray;dayArray.append(day0);dayArray.append(day1);dayArray.append(day2);rootObj["days"] = dayArray;//通過QJsonDocument把JSON數據轉換成QByteArrayQJsonDocument jsonDoc(rootObj);QByteArray jsonArry = jsonDoc.toJson();QFile file("D:/QT/test.json");file.open(QIODevice::WriteOnly);file.write(jsonArry);file.close();}
Widget::~Widget()
{delete ui;
}
QT解析JSON數據
? 在Qt中解析JSON數據通常涉及到使用 QJsonDocument
、 QJsonObject
和 QJsonArray
類。這些類提供了處理JSON數據的必要工具,使您能夠從JSON字符串中提取信息、遍歷JSON對象或數組,并訪問具體的數據項。以下是一個基本的示例,展示了如何在Qt中解析JSON字符串。
示例:解析JSON字符串
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"skills": ["C++", "Python", "JavaScript"]
}
以下是如何在Qt中解析這個JSON字符串的步驟:
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
void parseJson() {// JSON字符串/*
R 是用于定義原始字符串字面量(Raw String Literal)的標記。
在C++中,原始字符串字面量是一種方便的語法,
用于創建包含多行文本和特殊字符的字符串,而無需轉義。
R"("chenlichen")"
*/QString testStr = "chenli\"c";QString jsonString = R"(
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"skills": ["C++", "Python", "JavaScript"]
}
)";/*jsonString = "{\n"
" \"name\": \"John Doe\",\n"
" \"age\": 30\n"
"}";
*/// 將JSON字符串轉換為QJsonDocumentQJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());// 檢查JSON文檔是否包含一個對象if (!jsonDoc.isNull() && jsonDoc.isObject()) {// 獲取JSON對象QJsonObject jsonObj = jsonDoc.object();// 訪問對象的鍵值QString name = jsonObj["name"].toString();int age = jsonObj["age"].toInt();QString email = jsonObj["email"].toString();qDebug() << "Name:" << name;qDebug() << "Age:" << age;qDebug() << "Email:" << email;// 處理JSON數組if (jsonObj.contains("skills") && jsonObj["skills"].isArray()) {QJsonArray skillsArray = jsonObj["skills"].toArray();for (const QJsonValue &value : skillsArray) {qDebug() << "Skill:" << value.toString();}}} else {qDebug() << "Invalid JSON...";}
}
int main() {parseJson();return 0;
}