医院网站源码asp,vancl官网,怎么做钓qq密码网站,网站备案需要多少时间参考引用 QT开发专题-天气预报 1. JSON 数据格式
1.1 什么是 JSON
JSON (JavaScript Object Notation)#xff0c;中文名 JS 对象表示法#xff0c;因为它和 JS 中对象的写法很类似 通常说的 JSON#xff0c;其实就是 JSON 字符串#xff0c;本质上是一种特殊格式的字符串… 参考引用 QT开发专题-天气预报 1. JSON 数据格式
1.1 什么是 JSON
JSON (JavaScript Object Notation)中文名 JS 对象表示法因为它和 JS 中对象的写法很类似 通常说的 JSON其实就是 JSON 字符串本质上是一种特殊格式的字符串JSON 是一种轻量级的数据交换格式客户端和服务端数据交互基本都是 JSON 格式的 JSON 有以下特点 便于阅读和书写 除了 JSON 格式还有一种数据传输格式 XML相对于 XMLJSON 更加便于阅读和书写独立于编程语言 网络传输的标准数据格式完全独立于编程语言 几乎在所有的编程语言和开发环境中都有解析和生成 JSON 字符串的库 // C
Jansson cJSON// C
jsonCpp、JSON for Modern C// Java
json-lib、org-json// Qt
QJSONxxx1.2 JSON 的两种数据格式 JSON 有两种数据格式 JSON 对象被大括号包裹JSON 数组被中括号包裹 1.2.1 JSON 数组
JSON 数组格式[元素1, 元素2, 元素3, ... 元素n]类似于 c/C 中的数组元素之间以逗号分隔。不同的是JSON 数组中的元素可以是不同的数据类型 包括整型、浮点、字符串、布尔类型、JSON 数组、JSON 对象、空值 // JSON 数组中的元素是同一类型
[1, 2, 3, 4]
[Spring, Summer, Autumn, Winter]// JSON 数组中的元素是不同类型
[1, 2.5, hello, true, false, null]// JSON 数组的嵌套
[[1, 2, 3, 4],[Spring, Summer, Autumn, Winter],[1, 2.5, hello, true, false, null]
]// JSON 数组嵌套 JSON 对象
[{name: Tom,age: 18,gender: male}{name: Lucy,age: 20,gender: female}
]1.2.2 JSON 对象
JSON 对象格式{key1: value1,key2: value2,key3: value3
}JSON 对象内部使用键值对的方式来组织 键和值之间使用冒号分隔多个键值之间使用逗号分隔键是字符串类型值的类型可以是整型、浮点、字符串、布尔类型、JSON 数组、JSON 对象、空值 {name: Tom,age: 18,gender: male
}JSON 对象中还可以嵌套 JSON 对象和 JSON 数组{name: China,info: {capital: beijing,asian: true,founded: 1949},provinces: [{name: hunan,capital: changsha}, {name: hubei,capital: wuhan}]
}1.3 JSON 在线解析
JSON 本质就是一种特殊格式的字符串 实际工作中这个 JSON 字符串可能是自己手写的也可能是来自网络接收的数据 下面的一段 JSON 字符串它可能是自己写的也可能是服务端返回的 它是压缩的格式也就是没有换行和缩进不方便判断格式是否正确可以通过 JSON 在线解析工具来校验这个 JSON 的格式是否正确 {name:China,info:{capital:beijing,asian:true,founded:1949},provinces:
[{name:hunan,capital:changsha},{name:hubei,capital: huhan}]}1.4 Qt 中使用 JSON
1.4.1 JSON 相关的类
1QJsonObject
QJsonObject 封装了 JSON 中的对象可以存储多个键值对 其中键为字符串类型值为 QJsonValue 类型 创建一个 QJsonObject 对象QJsonObject::QJsonObject();将键值对添加到 QJsonObject 对象中QJsonObject::iterator insert(const QString key, const QJsonValue value);获取 QJsonObject 对象中键值对的个数int QJsonObject::count() const;
int QJsonObject::size() const;
int QJsonObject::length() const;通过 key 得到 valueQJsonValue QJsonObject::value(const QString key) const;
QJsonValue QJsonObject::operator[](const QString key) const;检查 key 是否存在iterator QJsonObject::find(const QString key);
bool QJsonObject::contains(const QString key) const;遍历 keyQStringList QJsonObject::keys() const;2QJsonArray
QJsonArray 封装了 Json 中的数组数组中元素类型统一为 QJsonValue 类型创建一个 QJsonArrayQJsonArray::QJsonArray();添加数组元素// 添加到头部和尾部
void QJsonArray::append(const QJsonValue value);
void QJsonArray::prepend(const QJsonValue value);// 插入到 i 的位置之前
void QJsonArray::insert(int i, const QJsonValue value);// 添加到头部和尾部
void QJsonArray::push_back(const QJsonValue value);
void QJsonArray::push_front(const QJsonValue value);获取 QJsonArray 中元素个数int QJsonArray::count() const;
int QJsonArray::size() const;获取元素的值// 获取头部和尾部
QJsonValue QJsonArray::first() const;
QJsonValue QJsonArray::last() const;// 获取指定位置
QJsonValue QJsonArray::at(int i) const;
QJsonValueRef QJsonArray::operator[](int i);删除元素// 删除头部和尾部
void QJsonArray::pop_back();
void QJsonArray::pop_front();void QJsonArray::removeFirst();
void QJsonArray::removeLast();// 删除指定位置
void QJsonArray::removeAt(int i);
QJsonValue QJsonArray::takeAt(int i);3QJsonValue 封装了 JSON 支持的六种数据类型 QJsonValue::Bool // 布尔类型
QJsonValue::Double // 浮点含整型类型
QJsonValue::String // 字符串类型
QJsonValue::Array // Json 数组类型
QJsonValue::Object // Json 对象类型
QJsonValue::Null // 空值类型可以通过以下方式构造 QJsonValue 对象 // 字符串
QJsonValue(const char *s);
QJsonValue(QLatin1String s);
QJsonValue(const QString s);// 整型 and 浮点型
QJsonValue(qint64 v);
QJsonValue(int v);
QJsonValue(double v);// 布尔类型
QJsonValue(bool b);// Json 对象
QJsonValue(const QJsonObject o);// Json 数组
QJsonValue(const QJsonArray a);// 空值类型
QJsonValue(QJsonValue::Type type Null);判断一个 QJsonValue 对象内部封装数据类型 // 是否是字符串类型
bool isString() const;// 是否是浮点类型(整形也是通过该函数判断)
bool isDouble const;// 是否是布尔类型
bool isBool() const;// 是否是Json对象
bool isObject() const;// 是否是 Json 数组
bool isArray() const;// 是否是未定义类型(无法识别的类型)
bool isUndefined() const;// 是否是空值类型
bool isNull() const;数据类型之间的转换 API 函数 // 转换为字符串类型
QString toString() const;
QString toString(const QString defaultValue) const;// 转换为浮点类型
double toDouble(double defaultValue 0) const;// 转换为整形
int toInt(int defaultValue 0) const;// 转换为布尔类型
bool toBool(bool defaultValue false) const;// 转换为 Json 对象
QJsonObject toObject() const;
QJsonObject toObject(const QJsonObject defaultValue) const;// 转换为 Json 数组
QJsonArray toArray() const;
QJsonArray toArray(const QJsonArray defaultValue) const;3QJsonDocument 它封装了一个完整的 JSON 文档 它可以从 UTF-8 编码的基于文本的表示以及 Qt 本身的二进制格式读取和写入该文档QJsonObject 和 QJsonArray 不能直接转换为字符类型需通过 QJsonDocument 来完成二者的转换 QJsonObject/QJsonArray 字符串 // 1. 创建 QJsonDocument 对象
// 以 QJsonObject 或 QJsonArray 为参数来创建 QJsonDocument 对象
QJsonDocument::QJsonDocument(const QJsonObject object);
QJsonDocument::QJsonDocument(const QJsonArray array);// 2. 将 QJsonDocument 对象中的数据进行序列化
// 通过调用 toXXX() 方法就可得到文本格式或者二进制格式的 Json 字符串
QByteArray QJsonDocument::toBinaryData() const; // 二进制格式的 json 字符串
QByteArray QJsonDocument::toJson(JsonFormat format Indented) const; // 文本格式// 3. 使用得到的字符串进行数据传输或者保存到文件字符串 QJsonObject/QJsonArray 通常通过网络接收或者读取磁盘文件会得到一个 JSON 格式的字符审之后可以按照如下步骤解析出 JSON 字符串中的一个个字段 // 1. 将 JSON 字符串转换为 QJsonDocument 对象
[static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray dataDataValidation validation Validate);
[static] QJsonDocument QJsonDocument::fromJson(const QByteArray json, QJsonParseError *error Q_NULLPTR);// 2. 将文档对象转换为 json 数组 / 对象
// 2.1 判断文档对象中存储的数据是 JSON 数组还是 JSON 对象
bool QJsonDocument::isArray() const;
bool QJsonDocument::isObject() const;// 2.2 转换为 JSON 数组或 JSON 对象
QJsonObject QJsonDocument::object() const;
QJsonArray QJsonDocument::array() const;// 3. 调用 QJsonArray / QJsonObject 类提供的 API 获取存储在其中的数据1.4.2 构建 JSON 字符串
在网络传输时通常是传输的 JSON 字符串传输之前首先要生成 JSON 字符串 接下来使用 Qt 提供的工具类来生成如下格式的 JSON 字符串 {name: China,info: {capital: beijing,asian: true,founded: 1949},provinces: [{name: hunan,capital: changsha}, {name: hubei,capital: wuhan}]
}代码实现#include QCoreApplication#include QJsonObject
#include QJsonArray
#include QJsonDocument#include QFile
#include QByteArray
#include QDebug
#include QStringvoid writeJson() {QJsonObject rootObj;// 1. 插入 name 字段rootObj.insert(name, China);// 2. 插入 info 字段QJsonObject infoObj;infoObj.insert(capital, beijing);infoObj.insert(asian, true);infoObj.insert(founded, 1949);rootObj.insert(info, infoObj);// 3. 插入 provinces 字段QJsonArray provinceArray;QJsonObject hunanObj;hunanObj.insert(name, hunan);hunanObj.insert(capital, changsha);QJsonObject hubeiObj;hubeiObj.insert(name, hubei);hubeiObj.insert(capital, wuhan);provinceArray.append(hunanObj);provinceArray.append(hubeiObj);rootObj.insert(provinces, provinceArray);// 4. 将 QJsonObject 对象 rootObj 转换为 Json 字符串QJsonDocument doc(rootObj);QByteArray json doc.toJson();// 5.1 打印输出qDebug() QString(json).toUtf8().data();// 5.2 将 json 字符串写入文件QFile file(d:\\china.json);file.open(QFile::WriteOnly);file.write(json);file.close();
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);writeJson();return a.exec();
}1.4.3 解析 JSON 字符串
通常接收网络数据的格式是JSON 格式在接收完毕之后需要解析出其中的每一个字段根据各个字段的值做相应的显示或者其他处理
#include QCoreApplication#include QJsonObject
#include QJsonArray
#include QJsonDocument
#include QJsonValue#include QFile
#include QByteArray
#include QDebug
#include QString
#include QStringListvoid fromJson() {// 1. 读取文件QFile file(d:\\china.json);file.open(QFile::ReadOnly);QByteArray json file.readAll();file.close();QJsonDocument doc QJsonDocument::fromJson(json);if (!doc.isObject()) {qDebug() Not an object!;return;}// 2. 开始解析QJsonObject obj doc.object();QStringList keys obj.keys();for (int i 0; i keys.size(); i) {// 获取 key-value 对QString key keys[i];QJsonValue value obj.value(key);if (value.isBool()) {qDebug() key : value.toBool();} else if (value.isString()) {qDebug() key : value.toString();} else if (value.isDouble()) {qDebug() key : value.toInt();} else if (value.isObject()) {qDebug() key :;QJsonObject infoObj value.toObject();QString capital infoObj[capital].toString();bool asian infoObj[asian].toBool();int founded infoObj[founded].toInt();qDebug() capital capital;qDebug() asian asian;qDebug() founded founded;} else if (value.isArray()) {qDebug() key;QJsonArray provinceArray value.toArray();for (int i 0; i provinceArray.size(); i) {QJsonObject provinceObj provinceArray[i].toObject();QString name provinceObj[name].toString();QString capital provinceObj[capital].toString();qDebug() name : name , capital : capital;}}}
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);fromJson();return a.exec();
}控制台输出info :capital beijingasian truefounded 1949
name : China
provincesname : hunan , capital : changshaname : hubei , capital : wuhan2. HTTP 通信
2.1 HTTP 概述 HTTP超文本传输协议 (HyperText Transfer Protocol)HTTP 是浏览器端 web 通信的基础 2.1.1 两种架构
B/S 架构Browser/server浏览器/服务器架构 B浏览器比如 Firefox、Internet Explorer、Google Chrome、Safari、Opera 等S服务器比如 Apache、nginx 等 C/S 架构client/server客户端/服务器架构 B/S 架构相对于 C/S 架构客户机上无需安装任何软件使用浏览器即可访问服务器因此越来越多的 C/S 架构正被 B/S 架构所替代
2.1.2 基于请求响应的模式
HTTP 协议永远都是客户端发起请求服务器做出响应 也就是说请求必定是先从客户端发起的服务器端在没有接收到请求之前不会发送任何响应这就无法实现这样一种场景服务端主动推送消息给客户端
2.1.3 无状态 当浏览器第一次发送请求给服务器时服务器做出了响应 当浏览器第二次发送请求给服务器时服务器同样可以做出响应但服务器并不知道第二次的请求和第一次来自同一个浏览器 也就是说服务器不会记住你是谁所以是无状态的 而如果要使 HTTP 协议有状态就可以使浏览器访问服务器时加入 cookie这样只要你在请求时有了这个 cookie服务器就能够通过 cookie 知道你就是之前那个浏览器这样HTTP 协议就有状态了
2.1.4 请求保文 请求报文由四部分组成 请求行 请求头请求首部字段 空行 实体 请求行 请求方法比如 GET、POST资源对象 (URL)协议名称和版本号 (HTTP/1.1) 请求头请求首部字段 请求头用于告诉服务器该请求的一些信息起到传递额外信息的目的 空行 空行是为了区分请求头和请求实体 请求实体 请求实体即真正所需要传输的数据
2.1.5 响应保文 响应报文同样是由四部分组成 状态行 响应头响应报文首部 空行 消息体 状态行 HTTP 版本状态码 (表示相应的结果)原因短语 (解释) 响应头响应报文首部 和请求报文首部一样响应报文首部同样是为了传递额外信息 空行 同样是为了区别响应实体和响应首部 响应实体 真正存储响应信息的部分
2.1.6 请求方式
HTTP 常用的请求方式有很多中最常用的是 GET 和 POST二者最主要的区别就是 GET 请求的参数位于 URL 中会显示在地址栏上POST 请求的参数位于 request body 请求体中 因此GET 请求的安全性不如 POST 请求并且 GET 请求的参数有长度限制而 POST 没有 2.2 调试利器 Postman
HTTP 包含客户端和服务端试想下面的两种情况Postman 使用场景 服务端开发完毕而客户端还未完成开发此时服务端开发人员能否对自己写的服务端程序进行测试呢?客户端开发人员访问服务端出错比如无法访问服务端有没有第三方的测试工具做进一步验证呢? Postman 是一个接口测试工具主要是用来模拟各种 HTTP 请求 (比如 GET 请求、POST 请求等)在做接口测试的时候Postman 相当于客户端它可模拟用户发起的各类 HTTP 请求将请求数据发送至服务端并获取对应的响应结果
2.2.1 安装
Postman 下载
2.2.2 发送请求
这里以获取北京的天气为例 获取北京天气的 URL 为http://t.weather.itboy.net/api/weather/city/101010100其中101010100 是北京的城市编码是 9 位的 2.3 Qt 实现 HTTP 请求
2.3.1 创建 “网络访问管理” 对象
首先需要创建一个 QNetworkAccessManager 对象这是 Qt 中进行 HTTP 请求的开端mNetAccessManager new QNetworkAccessManager(this);2.3.2 关联信号槽
在发送 HTTP 请求之前先关联信号槽// 获取到数据之后
connect(mNetAccessManager, QNetworkAccessManager::finished, this, MainWindow::onReplied);2.3.3 发送请求
根据请求的地址构建出一个 Qurl 对象然后直接调用 QNetworkAccessManager 的 get 方法即可发送一个 GET 请求Qurl ur1(http://t.weather.itboy.net/api/weather/city/101010100);
mNetAccessManager-get(QNetworkRequest(url));2.3.4 接收数据
由于上面绑定了信号槽服务器返回数据后自动调用自定义的槽函数 onReplied 如下是 onReplied 函数的标准写法QNetworkReply 中封装了服务器返回的所有数据包括响应头、响应的状态码、响应体等 void MainWindow::onReplied(QNetworkReply *reply) {// 响应的状态码为200表示请求成功int status_code reply-attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug() operation: reply-operation(); // 请求方式qDebug() status code: status_code; // 状态码qDebug() url: reply-url(); // urlqDebug() raw header: reply-rawHeaderList(); // headerif (reply-error() ! QNetworkReply::NoError || status_code ! 200) {QMessageBox::warning(this, 提示, 请求数据失败, QMessageBox::OK);} else {// 获取响应信息QByteArray reply_data reply-readAll();QByteArray byteArray QString(reply_data).toUtf8();qDebug() read all: byteArray.data();// parseJson()}reply-deleteLater();
}3. 详细代码实现
WeatherForecast