Qt中利用QJsonDocument实现安全的JSON序列化/反序列化方案,包含详细的错误 ...

打印 上一主题 下一主题

主题 1807|帖子 1807|积分 5421

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
以下是在Qt中利用QJsonDocument实现安全的JSON序列化/反序列化方案,包含详细的错误处置惩罚机制:
1. 底子错误处置惩罚架构
  1. class JsonSerializable {
  2. public:
  3.     virtual ~JsonSerializable() = default;
  4.   
  5.     // 序列化接口
  6.     [[nodiscard]] bool serialize(QByteArray &output) const {
  7.         QJsonObject jsonObj;
  8.         if (!toJson(jsonObj)) {
  9.             m_lastError = "Serialization failed: " + m_lastError;
  10.             return false;
  11.         }
  12.       
  13.         // 生成紧凑格式JSON(改用QJsonDocument::Indented可调格式)
  14.         output = QJsonDocument(jsonObj).toJson(QJsonDocument::Compact);
  15.         return true;
  16.     }
  17.     // 反序列化接口
  18.     [[nodiscard]] bool deserialize(const QByteArray &input) {
  19.         QJsonParseError parseError;
  20.         QJsonDocument doc = QJsonDocument::fromJson(input, &parseError);
  21.       
  22.         if (parseError.error != QJsonParseError::NoError) {
  23.             m_lastError = QString("JSON parse error at %1: %2")
  24.                           .arg(parseError.offset)
  25.                           .arg(parseError.errorString());
  26.             return false;
  27.         }
  28.       
  29.         if (!doc.isObject()) {
  30.             m_lastError = "Root is not a JSON object";
  31.             return false;
  32.         }
  33.       
  34.         return fromJson(doc.object());
  35.     }
  36.     // 错误信息访问
  37.     QString lastError() const { return m_lastError; }
  38. protected:
  39.     // 子类必须实现的JSON转换方法
  40.     virtual bool toJson(QJsonObject &json) const = 0;
  41.     virtual bool fromJson(const QJsonObject &json) = 0;
  42.     // 错误处理辅助方法
  43.     void setError(const QString &error) { m_lastError = error; }
  44.     bool validateField(const QJsonObject &json,
  45.                       const QString &key,
  46.                       QJsonValue::Type expectedType) {
  47.         if (!json.contains(key)) {
  48.             m_lastError = QString("Missing required field: %1").arg(key);
  49.             return false;
  50.         }
  51.         if (json[key].type() != expectedType) {
  52.             m_lastError = QString("Field '%1' type mismatch (Expect:%2 Got:%3)")
  53.                           .arg(key)
  54.                           .arg(typeToString(expectedType))
  55.                           .arg(typeToString(json[key].type()));
  56.             return false;
  57.         }
  58.         return true;
  59.     }
  60. private:
  61.     QString m_lastError;
  62.   
  63.     static QString typeToString(QJsonValue::Type type) {
  64.         switch(type) {
  65.         case QJsonValue::Null:   return "Null";
  66.         case QJsonValue::Bool:   return "Bool";
  67.         case QJsonValue::Double: return "Double";
  68.         case QJsonValue::String: return "String";
  69.         case QJsonValue::Array:  return "Array";
  70.         case QJsonValue::Object: return "Object";
  71.         default:                 return "Unknown";
  72.         }
  73.     }
  74. };
复制代码
2. 具体数据类实现示例
  1. class UserProfile : public JsonSerializable {
  2. public:
  3.     // 必须字段
  4.     QString username;
  5.     QString email;
  6.     int age = 0;
  7.     // 可选字段
  8.     QString phoneNumber;
  9.     QDateTime registrationDate;
  10. protected:
  11.     bool toJson(QJsonObject &json) const override {
  12.         // 验证数据有效性
  13.         if (username.isEmpty() ||
  14.             !email.contains('@') ||
  15.             age < 0)
  16.         {
  17.             setError("Invalid user data");
  18.             return false;
  19.         }
  20.         // 序列化必须字段
  21.         json["username"] = username;
  22.         json["email"] = email;
  23.         json["age"] = age;
  24.         // 序列化可选字段
  25.         if (!phoneNumber.isEmpty())
  26.             json["phone"] = phoneNumber;
  27.         if (registrationDate.isValid())
  28.             json["reg_date"] = registrationDate.toString(Qt::ISODate);
  29.         return true;
  30.     }
  31.     bool fromJson(const QJsonObject &json) override {
  32.         // 验证必须字段
  33.         if (!validateField(json, "username", QJsonValue::String) ||
  34.             !validateField(json, "email", QJsonValue::String) ||
  35.             !validateField(json, "age", QJsonValue::Double))
  36.         {
  37.             return false;
  38.         }
  39.         // 解析必须字段
  40.         username = json["username"].toString();
  41.         email = json["email"].toString();
  42.         age = json["age"].toInt();
  43.         // 检查有效性
  44.         if (username.isEmpty()) {
  45.             setError("Username cannot be empty");
  46.             return false;
  47.         }
  48.         if (!email.contains('@')) {
  49.             setError("Invalid email format");
  50.             return false;
  51.         }
  52.         if (age < 0) {
  53.             setError("Age cannot be negative");
  54.             return false;
  55.         }
  56.         // 解析可选字段
  57.         if (json.contains("phone")) {
  58.             if (json["phone"].type() != QJsonValue::String) {
  59.                 setError("Invalid phone number format");
  60.                 return false;
  61.             }
  62.             phoneNumber = json["phone"].toString();
  63.         }
  64.         if (json.contains("reg_date")) {
  65.             if (!json["reg_date"].isString()) {
  66.                 setError("Invalid registration date format");
  67.                 return false;
  68.             }
  69.             registrationDate = QDateTime::fromString(
  70.                 json["reg_date"].toString(),
  71.                 Qt::ISODate
  72.             );
  73.             if (!registrationDate.isValid()) {
  74.                 setError("Malformed registration date");
  75.                 return false;
  76.             }
  77.         }
  78.         return true;
  79.     }
  80. };
复制代码
3. 加强的错误处置惩罚拓展
  1. class SafeJsonConverter {
  2. public:
  3.     // 带详细错误信息的泛型转换接口
  4.     template<typename T>
  5.     static bool fromJson(const QByteArray &jsonData, T &obj) {
  6.         static_assert(std::is_base_of_v<JsonSerializable, T>,
  7.                      "T must inherit from JsonSerializable");
  8.         if (!obj.deserialize(jsonData)) {
  9.             m_lastGlobalError = obj.lastError();
  10.             return false;
  11.         }
  12.         return true;
  13.     }
  14.     template<typename T>
  15.     static QByteArray toJson(const T &obj, bool *ok = nullptr) {
  16.         static_assert(std::is_base_of_v<JsonSerializable, T>,
  17.                      "T must inherit from JsonSerializable");
  18.         QByteArray result;
  19.         bool success = obj.serialize(result);
  20.         if (ok) *ok = success;
  21.         if (!success) m_lastGlobalError = obj.lastError();
  22.         return result;
  23.     }
  24.     static QString lastError() { return m_lastGlobalError; }
  25. private:
  26.     inline static QString m_lastGlobalError;
  27. };
复制代码
4. 利用示例及错误处置惩罚

[code]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()
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表