使用boost::json访问嵌套JSON报错,如何修复?
Boost.JSON解析嵌套对象报错"not a string"的修复方案
问题背景
给定JSON数据:
{ "type": "test", "version": 1, "data": { "name": "omni", "id": "123", "value": 3 } }
尝试用以下C++函数处理时,在解析data字段时抛出异常:
void process_data(std::string type, std::string data) { boost::json::value data = boost::json::parse(data); // 变量名重复,覆盖参数 std::string name = json.at("name").as_string().c_str(); std::string id = json.at("id").as_string().c_str(); int value = json.at("value").as_int64(); std::cout << "Message data content:" << std::endl; std::cout << "Name: " << name << std::endl; std::cout << "Id: " << id << std::endl; std::cout << "Value: " << value << std::endl; } void process_message(std::string payload) { boost::json::value json = boost::json::parse(payload); std::string type = json.at("type").as_string().c_str(); int version = json.at("version").as_int64(); std::cout << "Message received:" << std::endl; std::cout << "Type: " << type << std::endl; std::cout << "Version: " << version << std::endl; std::string data = json.at("data").as_string().c_str(); // 报错行 process_data(data); // 缺少type参数 }
抛出的错误信息:
terminate called after throwing an instance of 'boost::wrapexcept<std::invalid_argument>' what(): not a string Aborted (core dumped)
错误原因
- 核心问题:JSON中的
data是嵌套对象,而非字符串,代码中调用as_string()尝试将对象转为字符串,触发类型不匹配异常。 - 次要问题:
process_data函数中局部变量data与参数data重名,导致逻辑错误;- 调用
process_data时未传入type参数,不符合函数签名要求; as_int64()返回int64_t类型,直接赋值给int存在隐式类型转换风险。
修复步骤
方案一:直接传递JSON对象(推荐,效率更高)
- 修改
process_data参数,直接接收boost::json::value对象,避免重复解析:void process_data(std::string type, boost::json::value const& data) { std::string name = data.at("name").as_string().c_str(); std::string id = data.at("id").as_string().c_str(); // 显式转换int64_t到int,确保类型安全 int value = static_cast<int>(data.at("value").as_int64()); std::cout << "Message data content:" << std::endl; std::cout << "Name: " << name << std::endl; std::cout << "Id: " << id << std::endl; std::cout << "Value: " << value << std::endl; } - 在
process_message中直接获取嵌套的data对象并传递:void process_message(std::string payload) { boost::json::value json = boost::json::parse(payload); std::string type = json.at("type").as_string().c_str(); int version = static_cast<int>(json.at("version").as_int64()); std::cout << "Message received:" << std::endl; std::cout << "Type: " << type << std::endl; std::cout << "Version: " << version << std::endl; // 直接获取data对象,无需转为字符串 boost::json::value const& data = json.at("data"); process_data(type, data); }
方案二:序列化JSON对象为字符串(仅在必须传递字符串时使用)
如果业务逻辑要求必须传递字符串,可将JSON对象序列化为字符串后再传递:
- 修改
process_message中的代码:void process_message(std::string payload) { // ... 原有代码不变 ... // 将data对象序列化为字符串 std::string data_str = boost::json::serialize(json.at("data")); process_data(type, data_str); } - 修正
process_data中的变量名重复问题:void process_data(std::string type, std::string data_str) { boost::json::value data = boost::json::parse(data_str); std::string name = data.at("name").as_string().c_str(); std::string id = data.at("id").as_string().c_str(); int value = static_cast<int>(data.at("value").as_int64()); // ... 原有输出逻辑不变 ... }
内容的提问来源于stack exchange,提问作者Mendes
相关产品推荐
相关产品推荐

