C++和Java在JSON解析上的区别
c++由于没有java的反射机制,所以是不可能通过代码自动获取类字段的
因此不可能完全像java那样,只要一行代码,就可以实现任意json字符串和任意类对象之间的转换
不管使用什么c++ json解析库,我们都需要手动去指定字段名,字段值,字段类型
我们能做的,是尽量让解析代码更清晰,不要让繁琐的解析代码和业务代码混到一起,影响可读性
这里我们只介绍Qt自带的解析库,其它c++库同理
类模型
本篇文章以以下两个类来作为JSON测试数据
class Score {
public:
int math;
int chinese;
int english;
};
class Person {
public:
QString name;
int age;
Score score;
};
测试JSON数据
//Person[]
[
{
"age": 25,
"name": "A",
"score": {
"chinese": 85,
"english": 90,
"math": 100
}
},
{
"age": 25,
"name": "B",
"score": {
"chinese": 85,
"english": 90,
"math": 100
}
},
{
"age": 25,
"name": "C",
"score": {
"chinese": 85,
"english": 90,
"math": 100
}
}
]
JsonDocument存储和读取
JsonDocument是对JSON数据结构的一种封装,它保存了所有字段的字段名,字段值,字段类型
JsonDocument即可以转换为类对象,也可以转换为文本,它是文本和类对象之间进行转换的中介
先讲JsonDocument,便于我们弄清原理,了解Qt JSON库的设计
QJsonDocument document;
//存储Person数组到JsonDocument中
QJsonArray jsonArray;
for (int i = 0; i < 3; i++) {
QJsonObject scoreObject;
scoreObject.insert("math", 100);
scoreObject.insert("chinese", 85);
scoreObject.insert("english", 90);
QJsonObject jsonObject;
jsonObject.insert("name", "ABC");
jsonObject.insert("age", 25);
jsonObject.insert("score", scoreObject);
jsonArray.append(jsonObject);
}
//设置JsonDocument根元素
document.setArray(jsonArray);
qdebug << document << endl;
//从JsonDocument中获取数值
int chineseScore = document.array()[0].toObject().value("score").toObject().value("chinese").toInt();
qdebug << chineseScore << endl;
JsonDocument和文本间的互转
//JsonDocument转String
QJsonDocument document;
QString json = document.toJson();
//String转JsonDocument
QString json;
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(json.toUtf8(), &error);
bool result = error.error == QJsonParseError::NoError;
JsonObject和对象间的互转
c++虽然不能像java那样全自动实现json和对象之间的转换
但是我们可以手动为每个类添加fromJsonObject和toJsonObject方法
这样在外部使用时,仍然可以通过一行代码直接转换,看起来仍然是自动转换,提升可读性
class Score {
public:
int math;
int chinese;
int english;
static Score fromJsonObject(QJsonObject jsonObject) {
Score score;
score.math = jsonObject.value("math").toInt();
score.chinese = jsonObject.value("chinese").toInt();
score.english = jsonObject.value("english").toInt();
return score;
}
QJsonObject toJsonObject() {
QJsonObject jsonObject;
jsonObject.insert("math", math);
jsonObject.insert("chinese", chinese);
jsonObject.insert("english", english);
return jsonObject;
}
};
class Person {
public:
QString name;
int age;
Score score;
static Person fromJsonObject(QJsonObject jsonObject) {
Person person;
person.name = jsonObject.value("name").toString();
person.age = jsonObject.value("age").toInt();
person.score = Score::fromJsonObject(jsonObject.value("score").toObject());
return person;
}
QJsonObject toJsonObject() {
QJsonObject jsonObject;
jsonObject.insert("name", name);
jsonObject.insert("age", age);
jsonObject.insert("score", score.toJsonObject());
return jsonObject;
}
};
JSON文本和对象间的互转
从文件中读取JSON字符串,转换为Person数组,并打印
QFile file("C:/1.json");
file.open(QFile::ReadWrite);
QJsonDocument document = QJsonDocument::fromJson(file.readAll());
int length;
Person* personArray = Person::fromJsonArray(document.array(), length);
for (int i = 0; i < length; i++)
cout << personArray[i].name.toStdString() << endl;
Person数组转换为JSON字符串,并打印
QJsonDocument document;
Person* personArray;
int length;
QJsonArray jsonArray = Person::toJsonArray(personArray, length);
document.setArray(jsonArray);
cout << document.toJson().toStdString() << endl;
和JsonObject一样,我们还为类添加了与JsonArray的互转方法
class Score {
public:
int math;
int chinese;
int english;
static Score fromJsonObject(QJsonObject jsonObject) {
Score score;
score.math = jsonObject.value("math").toInt();
score.chinese = jsonObject.value("chinese").toInt();
score.english = jsonObject.value("english").toInt();
return score;
}
static Score* fromJsonArray(QJsonArray jsonArray, int& length) {
length = jsonArray.size();
Score* scoreArray = new Score[length];
for (int i = 0; i < length; i++)
scoreArray[i] = Score::fromJsonObject(jsonArray.at(i).toObject());
return scoreArray;
}
static QJsonArray toJsonArray(Score* scoreArray, int length) {
QJsonArray jsonArray;
for (int i = 0; i < length; i++)
jsonArray.append(scoreArray[i].toJsonObject());
return jsonArray;
}
QJsonObject toJsonObject() {
QJsonObject jsonObject;
jsonObject.insert("math", math);
jsonObject.insert("chinese", chinese);
jsonObject.insert("english", english);
return jsonObject;
}
};
class Person {
public:
QString name;
int age;
Score score;
static Person fromJsonObject(QJsonObject jsonObject) {
Person person;
person.name = jsonObject.value("name").toString();
person.age = jsonObject.value("age").toInt();
person.score = Score::fromJsonObject(jsonObject.value("score").toObject());
return person;
}
static Person* fromJsonArray(QJsonArray jsonArray, int& length) {
length = jsonArray.size();
Person* personArray = new Person[length];
for (int i = 0; i < length; i++)
personArray[i] = Person::fromJsonObject(jsonArray.at(i).toObject());
return personArray;
}
static QJsonArray toJsonArray(Person* personArray, int length) {
QJsonArray jsonArray;
for (int i = 0; i < length; i++)
jsonArray.append(personArray[i].toJsonObject());
return jsonArray;
}
QJsonObject toJsonObject() {
QJsonObject jsonObject;
jsonObject.insert("name", name);
jsonObject.insert("age", age);
jsonObject.insert("score", score.toJsonObject());
return jsonObject;
}
};