一.序列化和反序列化理解
1.序列化和反序列化是数据处理中的两个重要概念,特别是在数据传输和存储时。结合 nlohmann::json
库,以下是对这两个概念的解释:
序列化
序列化是将对象转换为一种可以存储或传输的格式的过程。在 nlohmann::json
库中,序列化通常是将 C++ 对象转换为 JSON 格式的字符串。
2.反序列化
反序列化是将存储或传输的格式转换回对象的过程。在 nlohmann::json
库中,反序列化通常是将 JSON 格式的字符串转换回 C++ 对象。
二.参考的使用方式
1.序列化
#include <iostream>
#include <string>
#include “nlohmann/json.hpp”
struct Person {
std::string name;
int age;
};
// 定义序列化方法
void to_json(nlohmann::json& j, const Person& p) {
j = nlohmann::json{{“name”, p.name}, {“age”, p.age}};
}
int main() {
Person person = {“John Doe”, 30};
nlohmann::json j = person; // 序列化
std::cout << j.dump(4) << std::endl; // 输出 JSON 字符串
return 0;
}
#include <iostream>
#include <string>
#include “nlohmann/json.hpp”
struct Person {
std::string name;
int age;
};
2.反序列化
// 定义反序列化方法
void from_json(const nlohmann::json& j, Person& p) {
j.at(“name”).get_to(p.name);
j.at(“age”).get_to(p.age);
}
int main() {
std::string jsonString = R”({“name”: “John Doe”, “age”: 30})”;
nlohmann::json j = nlohmann::json::parse(jsonString);
Person person = j.get<Person>(); // 反序列化
std::cout << “Name: ” << person.name << “, Age: ” << person.age << std::endl;
return 0;
}
三.Demo构建
(一)参考位置信息:
要在你的项目中使用 nlohmann::json 库,你需要引入 json.hpp
头文件。以下是如何引入和使用该库的步骤:
- 下载
json.hpp
文件: 你可以从 nlohmann/json GitHub 仓库 下载最新版本的json.hpp
文件。你可以直接下载整个仓库的压缩包,或者只下载single_include/nlohmann/json.hpp
文件。 - 将
json.hpp
文件添加到你的项目中: 将下载的json.hpp
文件放到你的项目目录中,例如放在include
文件夹中。
在你的代码中包含 json.hpp
文件: 在需要使用 JSON 功能的源文件中包含 json.hpp
头文件。
(二)具体实现demo
#include <iostream> #include <vector> #include <string> #include "json.hpp" // 根据你的项目结构调整路径 struct FacebookConnectInsData_t { struct FacebookConnectInsInfo_t { std::string id; std::string name; std::string access_token; struct FacebookConnectInsAccountId_t { std::string id; }; FacebookConnectInsAccountId_t instagram_business_account; }; std::vector<FacebookConnectInsInfo_t> data; }; // 使用自定义宏定义序列化和反序列化方法 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(FacebookConnectInsData_t::FacebookConnectInsInfo_t::FacebookConnectInsAccountId_t, id) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(FacebookConnectInsData_t::FacebookConnectInsInfo_t, id, name, access_token, instagram_business_account) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(FacebookConnectInsData_t, data) //// 定义序列化方法 //void to_json(nlohmann::json& j, const FacebookConnectInsData_t::FacebookConnectInsInfo_t::FacebookConnectInsAccountId_t& p) { // j = nlohmann::json{{"id", p.id}}; //} // //void to_json(nlohmann::json& j, const FacebookConnectInsData_t::FacebookConnectInsInfo_t& p) { // j = nlohmann::json{ // {"id", p.id}, // {"name", p.name}, // {"access_token", p.access_token}, // {"instagram_business_account", p.instagram_business_account} // }; //} // //void to_json(nlohmann::json& j, const FacebookConnectInsData_t& p) { // j = nlohmann::json{{"data", p.data}}; //} // //// 定义反序列化方法 //void from_json(const nlohmann::json& j, FacebookConnectInsData_t::FacebookConnectInsInfo_t::FacebookConnectInsAccountId_t& p) { // j.at("id").get_to(p.id); //} // //void from_json(const nlohmann::json& j, FacebookConnectInsData_t::FacebookConnectInsInfo_t& p) { // j.at("id").get_to(p.id); // j.at("name").get_to(p.name); // j.at("access_token").get_to(p.access_token); // if (j.contains("instagram_business_account")) { // j.at("instagram_business_account").get_to(p.instagram_business_account); // } else { // p.instagram_business_account = FacebookConnectInsData_t::FacebookConnectInsInfo_t::FacebookConnectInsAccountId_t{}; // } //} // //void from_json(const nlohmann::json& j, FacebookConnectInsData_t& p) { // j.at("data").get_to(p.data); //} //// 自定义异常类 class JsonParseException : public std::exception { public: explicit JsonParseException(const std::string& message) : msg_(message) {} virtual const char* what() const noexcept override { return msg_.c_str(); } private: std::string msg_; }; // 宏定义,用于抛出异常并附加位置信息 #define THROW_EXCEPTION_WITH_LOCATION(ex) \ throw ex int main() { std::string jsonString = R"({ "data":[ { "id":"489780270890201", "name":"Fxtest3", "access_token":"EAAG7WZAgNVLQBO7j88UJO0ag4tAErVoFhGeRCUGimx8IjClDr2Lc1Cb5cZCVZBtJSvb8bm3vhZAbdeIYaxQyBzaUvjwigls4l7gOB0PwDilBGk6xQRbdtHSuKL6GrOzb304V3ZA96n2BVpTgzNO77tDsXITYD6zJq8WDWY5X2b9JtSGunHwZAMECtOTPYh2BOklXrBA2Nuf4AJSNb2253EsJWt", "instagram_business_account":{"id":"17841466430598351"} }, { "id":"443174595541934", "name":"\u516c\u5171\u4e3b\u9875\u4e8c-test", "access_token":"EAAG7WZAgNVLQBO9t8gzA6QkKXv9l9AfrjRTTiMTGGpPOgxQTZAN8eN0tHOkU1v0y2naLryxnOu7fdOGIQnOE7ymOs7MN8CkmtlX9V2XIZAZC9fT2Qzs9QgSSnxZBQDsxoFoAd1kG92ErwKMtZBOVb6f3vAQ7RUOOsICacxyGOhD8g0WntNvu0ZCBVFn8AO1olnZCX9l4vevZBM59INVKWvztWqME6" }, { "id":"408818272321246", "name":"\u516c\u5171\u4e3b\u9875\u4e00", "access_token":"EAAG7WZAgNVLQBOzK0ONtR1JKJvYZBqchURZCSucBkESmZBLy5ZCMhDrHJouS2eMQWZB6ihkv8ZApejNfa6MtOX2cXrhaPxq4Skp0ggbZCRRoM9mZAAvwl3lQ2LM3API8fKcwGZB27ZCEz7fkyTzMVgBJztUrK2suNDHH0tT646rZA4hOwRpf8WSViV3enzAOsrOGgjLGOywfnNp4wQQ0ZBITaagfjONGi", "instagram_business_account":{"id":"17841469640446032"} }, { "id":"442463848945616", "name":"FastFish", "access_token":"EAAG7WZAgNVLQBO6E3NUDSuthdRO79gxgNjwCAvGqmDYPBucBwSsYPJzMauygDLwzaRSmbZCx7NlAQLzAKUKFQdXyfqS6NSpVh66SuEuOVEu2Ys1zZANGu5glGMLAsrTPz6Ta12RoH9mJI4VqLVjUgj6v0J3rCpSPwFrlaSQ412zC2Hihx8HZA2RZBBdFbMlaG9zW1iwhjZC2bN5ErVELyz2GZBb" } ], "paging":{ "cursors":{ "before":"QVFIUmVnWldwSDludGZA6RVM4OVZAGTXZAydkNNdU9SMGlYWTVKQXhVb0RkYnBUTlFlMjRzVjlBNGg0SVRHLWV0QTAwcV90Sno5S01NbHJjZAkI3dWdnTmlKekR3", "after":"QVFIUk5paktDWUNpX2pLUjNaMS04SmpoM3dod0ZA1WGJVSHgyQ2tPVWxFYnNEVzNPYU5FLTRReUZAGaHFSaUZAqTTJEM1FYUVQwSGVfY1FUdmpqOVZAyNkkyckt3" } } })"; try { auto json = nlohmann::json::parse(jsonString); FacebookConnectInsData_t object = json.get<FacebookConnectInsData_t>(); std::cout << "JSON parsed and converted successfully!" << std::endl; for (const auto& info : object.data) { std::cout << "ID: " << info.id << std::endl; std::cout << "Name: " << info.name << std::endl; std::cout << "Access Token: " << info.access_token << std::endl; std::cout << "Instagram Business Account ID: " << info.instagram_business_account.id << std::endl; } } catch (nlohmann::json::parse_error& e) { JsonParseException ex(e.what()); THROW_EXCEPTION_WITH_LOCATION(ex); } catch (nlohmann::json::type_error& e) { JsonParseException ex(e.what()); THROW_EXCEPTION_WITH_LOCATION(ex); } catch (std::exception& e) { THROW_EXCEPTION_WITH_LOCATION(JsonParseException(e.what())); } return 0; } 四.结合异常函数检测序列化情况; 1.异常检测函数:
#ifndef BSNET_HTTPCLIENTEXCEPTIONS_H_
#define BSNET_HTTPCLIENTEXCEPTIONS_H_
#include <exception>
#include <string>
#include <numeric>
/*
* @brief: exceptions for httpclient module
*/
namespace httpclient {
class BaseException : public std::exception
{
public:
BaseException() = default;
BaseException(const std::exception& e) : std::exception(e) {}
#ifdef WIN32
BaseException(const std::string& msg) : std::exception(msg.c_str()) {}
#else
BaseException(const std::string& msg) : std::exception() {}
#endif
virtual void raise() const { throw *this; }
virtual BaseException* clone() const
{
return new BaseException{*this};
}
std::string where() const { return m_where; }
void setWhere(const std::string& w) { m_where = w;}
private:
std::string m_where;
};
class JsonParseException : public BaseException
{
public:
JsonParseException(const std::string& msg) : BaseException(msg) {}
void raise() const override { throw *this; }
JsonParseException* clone() const override
{
return new JsonParseException{*this};
}
};
class ConvertTypeException : public BaseException
{
public:
ConvertTypeException(const std::string& msg) : BaseException(msg) {}
void raise() const override { throw *this; }
ConvertTypeException* clone() const override
{
return new ConvertTypeException{*this};
}
};
class EmptyResponseException : public BaseException
{
public:
EmptyResponseException(const std::string& msg) : BaseException(msg) {}
void raise() const override { throw *this; }
EmptyResponseException* clone() const override
{
return new EmptyResponseException{ *this };
}
};
template<class ExceptionType>
static inline ExceptionType buildExceptionLocation(ExceptionType exception,
int fileLine,
const std::string& fileName,
const std::string& funcName)
{
std::vector<std::string> elements;
elements.reserve(3);
elements = { std::to_string(fileLine), fileName, funcName };
std::string result;
result = std::accumulate(elements.begin(), elements.end(), result, [](const std::string& lhs, const std::string& rhs) {
return lhs.empty() ? rhs : lhs + “:” + rhs;
});
exception.setWhere(result);
return std::move(exception);
}
} // namespace httpclient
#define THROW_EXCEPTION_WITH_LOCATION(exception_object) throw httpclient::buildExceptionLocation(exception_object, __LINE__, __FILE__, __FUNCTION__);
#endif // BSNET_HTTPCLIENTEXCEPTIONS_H_
2.转换实现函数:(其中的头文件、异步调用文件可以不参考)
#include “networkaccessor.h”
#include “json.hpp”
#include “httpclientexceptions.h”
#include “httpclientreply.h”
namespace httpclient {
template<class T>
prm::Promise<T> NetworkAccessor::request(const HttpClientRequest & req) const
{
static_assert(std::is_constructible_v<T>, “T is not default constructible.”);
return access1(req).then([](std::string raw_body){
raw_body = {};
if (raw_body.empty()) {
EmptyResponseException ex(“Empty response from server”);
THROW_EXCEPTION_WITH_LOCATION(ex);
}
try {
auto json = nlohmann::json::parse(raw_body);
T object = json.get<T>();
return object;
} catch (nlohmann::json::parse_error& e) {
JsonParseException ex(e.what());
THROW_EXCEPTION_WITH_LOCATION(ex);
} catch (nlohmann::json::type_error& e) {
ConvertTypeException ex(e.what());
THROW_EXCEPTION_WITH_LOCATION(ex);
} catch (std::exception& e) {
THROW_EXCEPTION_WITH_LOCATION(BaseException(e));
}
});
}
} // namespace httpclient
五.注意细节:
- 缺乏默认键的情况 : 反序列化失败,存在没有默认的键是,需要使用默认的。 采用NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT宏而不是NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE。即可解决问题。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)