Json结构
{
"name": "a",
"age": 14,
"class": "初一",
"address": null,
"member": [
{
"memberName":"b",
"age":56,
"work":".....",
"num":"13254484545"
},
{
"memberName":"c",
"age":56,
"work":".....",
"num":"13254484545"
},
{
"memberName":"d",
"age":56,
"work":".....",
"num":"13254484545"
}
]
}
Qt类需根据json结构定义
由json结构分析,需要包含两个类Class A和Class B
class A 包含成员name 、age 、class、 adress、 QList<B>
class B 包含成员memberName 、age 、work 、num
定义类结构
class A : public QObject
{
Q_OBJECT
public:
A();
~A();
A(const A& other)
{
setName(other.getName());
setAge(other.getAge());
setClass(other.getClass());
setAdress(other.getAdress());
setBlist(other.getBlist());
}
A& operator=(const A& other)
{
setName(other.getName());
setAge(other.getAge());
setClass(other.getClass());
setAdress(other.getAdress());
setBlist(other.getBlist());
return *this;
}
Q_PROPERTY(QString name READ getName WRITE setName)
Q_PROPERTY(int age READ getAge WRITE setAge)
Q_PROPERTY(QString class READ getClass WRITE setClass)
Q_PROPERTY(QString adress READ getAdress WRITE setAdress)
Q_PROPERTY(QList<QObject*> bList READ getBlist WRITE setBlist)
QString getName() const { return name; }
void setName(QString val) { name = val; }
int getAge() const { return age; }
void setAge(int val) { age = val; }
QString getClass() const { return class; }
void setClass(QString val) { class = val; }
QString getAdress() const { return adress; }
void setAdress(QString val) { adress = val; }
QList<QObject*> getBlist() const
{
QList<QObject*> resultList;
for (auto item : bList)
{
resultList.append(item.data());
}
return resultList;
}
void setBlist(QList<QObject*> val)
{
for (auto item : val)
{
auto dataPtr = static_cast<B*>(item);
if (dataPtr)
{
list.append(QSharedPointer<B>(dataPtr));
}
}
}
private:
QString name;
int age;
QString class;
QString adress;
QList<QSharedPointer<B>> bList;
}
class B : public QObject
{
Q_OBJECT
public:
B();
~B();
B(const A& other)
{
setName(other.getMemberName());
setAge(other.getAge());
setWork(other.getWork());
setNum(other.getNum());
}
B& operator=(const B& other)
{
setName(other.getMemberName());
setAge(other.getAge());
setWork(other.getWork());
setNum(other.getNum());
return *this;
}
Q_PROPERTY(QString memberName READ getMemberName WRITE setMemberName)
Q_PROPERTY(int age READ getAge WRITE setAge)
Q_PROPERTY(QString work READ getWork WRITE setWork)
Q_PROPERTY(QString num READ getNum WRITE setNum)
QString getMemberName() const { return memberName; }
void setMemberName(QString val) { memberName = val; }
int getAge() const { return age; }
void setAge(int val) { age = val; }
QString getWork() const { return work; }
void setWork(QString val) { work = val; }
QString getNum() const { return num; }
void setNum(QString val) { num = val; }
private:
QString memberName;
int age;
QString work;
QString num;
}
注册需要解析的子类
qRegisterMetaType<QSharedPointer<A>("QSharedPointer<A>");
qRegisterMetaType<QSharedPointer<B>("QSharedPointer<B>");
公共解析接口
void deserialization(const QString& jsonstr, QObject* obj, const QMap<QString/*parent*/, QString/*className*/>& classMap)
{
QJsonDocument doc = QJsonDocument::fromJson(jsonstr.toUtf8());
if (doc.isObject())
{
QJsonObject rootObject = doc.object();
const QMetaObject* metaObj = obj->metaObject();
QString currClassName = metaObj->className();
int propertyCount = metaObj->propertyCount();
for (int i = 0; i < propertyCount; ++i)
{
QMetaProperty property = metaObj->property(i);
const char* name = property.name();
if (property.type() == QVariant::UserType)
{
QString childClassName = classMap[currClassName];
if (!childClassName.isEmpty())
{
if (rootObject[QString(name)].isObject())
{
int type = QMetaType::type(childClassName.toUtf8().constData());
if (type != QMetaType::UnknownType)
{
void* instance = QMetaType::create(type);
QObject* objectInstance = static_cast<QObject*>(instance);
if (objectInstance)
{
QJsonObject jsonObject = rootObject[QString(name)].toObject();
QJsonDocument jsonDoc;
jsonDoc.setObject(jsonObject);
QString jsonstr = jsonDoc.toJson(QJsonDocument::Compact);
deserialization(jsonstr, objectInstance, classMap);
}
}
}
else if (rootObject[QString(name)].isArray())
{
QJsonArray array = rootObject[QString(name)].toArray();
QList<QObject*> dataList;
for (int i = 0; i < array.size(); i++)
{
int type = QMetaType::type(childClassName.toUtf8().constData());
if (type != QMetaType::UnknownType) {
void* instance = QMetaType::create(type);
QObject* objectInstance = static_cast<QObject*>(instance);
if (objectInstance)
{
QJsonObject jsonObject = array.at(i).toObject();
QJsonDocument jsonDoc;
jsonDoc.setObject(jsonObject);
QString jsonstr = jsonDoc.toJson(QJsonDocument::Compact);
deserialization(jsonstr, objectInstance, classMap);
dataList.append(objectInstance);
}
}
}
property.write(obj, QVariant::fromValue(dataList));
}
}
}
else
{
QJsonValue value = rootObject.value(QString(name));
if (!value.isUndefined() && !value.isNull() &&value.toVariant().isValid())
{
if (value.toVariant().canConvert(property.type()))
{
property.write(obj, value.toVariant());
}
}
}
}
}
else if (doc.isArray())
{
const QMetaObject* metaObj = obj->metaObject();
QString currClassName = metaObj->className();
int propertyCount = metaObj->propertyCount();
for (int i = 0; i < propertyCount; ++i)
{
QMetaProperty property = metaObj->property(i);
if (property.type() == QVariant::UserType)
{
QString childClassName = classMap[currClassName];
if (!childClassName.isEmpty())
{
QJsonArray dataArray = doc.array();
QList<QObject*> dataList;
for (int index = 0; index < dataArray.size(); index++)
{
if (dataArray.at(index).isObject())
{
QJsonObject rootObject = dataArray.at(index).toObject();
int type = QMetaType::type(childClassName.toUtf8().constData());
if (type != QMetaType::UnknownType) {
void* instance = QMetaType::create(type);
QObject* objectInstance = static_cast<QObject*>(instance);
if (objectInstance)
{
QJsonObject rootObject = dataArray.at(index).toObject();
QJsonDocument jsonDoc;
jsonDoc.setObject(rootObject);
QString jsonstr = jsonDoc.toJson(QJsonDocument::Compact);
deserialization(jsonstr, objectInstance, classMap);
dataList.append(objectInstance);
}
}
}
}
property.write(obj, QVariant::fromValue(dataList));
}
}
}
}
}
json解析
A* a = new A();
QMap<QString, QString> classMap;
classMap.insert("B", "B");
deserialization(json, A, classMap);