Qt中使用QJsonDocument实现安全的JSON序列化/反序列化方案,包含详细的错误处理机制
以下是在Qt中使用QJsonDocument实现安全的JSON序列化/反序列化方案,包含详细的错误处理机制:1. 基础错误处理架构
class JsonSerializable {
public:
virtual ~JsonSerializable() = default;
// 序列化接口
[] bool serialize(QByteArray &output) const {
QJsonObject jsonObj;
if (!toJson(jsonObj)) {
m_lastError = "Serialization failed: " + m_lastError;
return false;
}
// 生成紧凑格式JSON(改用QJsonDocument::Indented可调格式)
output = QJsonDocument(jsonObj).toJson(QJsonDocument::Compact);
return true;
}
// 反序列化接口
[] bool deserialize(const QByteArray &input) {
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(input, &parseError);
if (parseError.error != QJsonParseError::NoError) {
m_lastError = QString("JSON parse error at %1: %2")
.arg(parseError.offset)
.arg(parseError.errorString());
return false;
}
if (!doc.isObject()) {
m_lastError = "Root is not a JSON object";
return false;
}
return fromJson(doc.object());
}
// 错误信息访问
QString lastError() const { return m_lastError; }
protected:
// 子类必须实现的JSON转换方法
virtual bool toJson(QJsonObject &json) const = 0;
virtual bool fromJson(const QJsonObject &json) = 0;
// 错误处理辅助方法
void setError(const QString &error) { m_lastError = error; }
bool validateField(const QJsonObject &json,
const QString &key,
QJsonValue::Type expectedType) {
if (!json.contains(key)) {
m_lastError = QString("Missing required field: %1").arg(key);
return false;
}
if (json.type() != expectedType) {
m_lastError = QString("Field '%1' type mismatch (Expect:%2 Got:%3)")
.arg(key)
.arg(typeToString(expectedType))
.arg(typeToString(json.type()));
return false;
}
return true;
}
private:
QString m_lastError;
static QString typeToString(QJsonValue::Type type) {
switch(type) {
case QJsonValue::Null: return "Null";
case QJsonValue::Bool: return "Bool";
case QJsonValue::Double: return "Double";
case QJsonValue::String: return "String";
case QJsonValue::Array:return "Array";
case QJsonValue::Object: return "Object";
default: return "Unknown";
}
}
};2. 具体数据类实现示例
class UserProfile : public JsonSerializable {
public:
// 必须字段
QString username;
QString email;
int age = 0;
// 可选字段
QString phoneNumber;
QDateTime registrationDate;
protected:
bool toJson(QJsonObject &json) const override {
// 验证数据有效性
if (username.isEmpty() ||
!email.contains('@') ||
age < 0)
{
setError("Invalid user data");
return false;
}
// 序列化必须字段
json["username"] = username;
json["email"] = email;
json["age"] = age;
// 序列化可选字段
if (!phoneNumber.isEmpty())
json["phone"] = phoneNumber;
if (registrationDate.isValid())
json["reg_date"] = registrationDate.toString(Qt::ISODate);
return true;
}
bool fromJson(const QJsonObject &json) override {
// 验证必须字段
if (!validateField(json, "username", QJsonValue::String) ||
!validateField(json, "email", QJsonValue::String) ||
!validateField(json, "age", QJsonValue::Double))
{
return false;
}
// 解析必须字段
username = json["username"].toString();
email = json["email"].toString();
age = json["age"].toInt();
// 检查有效性
if (username.isEmpty()) {
setError("Username cannot be empty");
return false;
}
if (!email.contains('@')) {
setError("Invalid email format");
return false;
}
if (age < 0) {
setError("Age cannot be negative");
return false;
}
// 解析可选字段
if (json.contains("phone")) {
if (json["phone"].type() != QJsonValue::String) {
setError("Invalid phone number format");
return false;
}
phoneNumber = json["phone"].toString();
}
if (json.contains("reg_date")) {
if (!json["reg_date"].isString()) {
setError("Invalid registration date format");
return false;
}
registrationDate = QDateTime::fromString(
json["reg_date"].toString(),
Qt::ISODate
);
if (!registrationDate.isValid()) {
setError("Malformed registration date");
return false;
}
}
return true;
}
};3. 增强的错误处理拓展
class SafeJsonConverter {
public:
// 带详细错误信息的泛型转换接口
template<typename T>
static bool fromJson(const QByteArray &jsonData, T &obj) {
static_assert(std::is_base_of_v<JsonSerializable, T>,
"T must inherit from JsonSerializable");
if (!obj.deserialize(jsonData)) {
m_lastGlobalError = obj.lastError();
return false;
}
return true;
}
template<typename T>
static QByteArray toJson(const T &obj, bool *ok = nullptr) {
static_assert(std::is_base_of_v<JsonSerializable, T>,
"T must inherit from JsonSerializable");
QByteArray result;
bool success = obj.serialize(result);
if (ok) *ok = success;
if (!success) m_lastGlobalError = obj.lastError();
return result;
}
static QString lastError() { return m_lastGlobalError; }
private:
inline static QString m_lastGlobalError;
};4. 使用示例及错误处理
int main() { // 序列化测试 UserProfile user; user.username = "john_doe"; user.email = "john@example.com"; user.age = 30; user.phoneNumber = "+123456789"; QByteArray jsonData; if (!user.serialize(jsonData)) { qCritical()
页:
[1]