如何使用boost::json::value检查JSON键是否存在?
在Boost.JSON中检查JSON键是否存在的解决方案
你遇到的崩溃是因为boost::json::value::at()方法在访问不存在的键时会抛出std::out_of_range异常,以下是几种安全检查键存在性的方法,以及更优的实现方式:
方法一:使用contains()检查键存在性
通过as_object()将JSON值转为对象后,调用contains()方法判断键是否存在,仅当键存在时才取值:
void checkMessage(std::string msg) { boost::json::value json = boost::json::parse(msg); // 确保JSON是对象类型,避免后续操作异常 if (!json.is_object()) { std::cerr << "Invalid JSON object" << std::endl; return; } auto obj = json.as_object(); // 必须存在的键仍用at(),缺失时抛异常快速定位问题 auto type = obj.at("type").as_string(); auto param1 = obj.at("param1").as_string(); // 处理可选键param2,不存在时使用默认值 int64_t param2 = 0; if (obj.contains("param2")) { param2 = obj.at("param2").as_int64(); } std::cout << "Received: " << std::endl; std::cout << "type: " << type << std::endl; std::cout << "param1: " << param1 << std::endl; std::cout << "param2: " << param2 << std::endl; }
方法二:使用find()查找键
find()方法返回指向键值对的迭代器,若键不存在则等于obj.end(),通过迭代器判断后取值:
void checkMessage(std::string msg) { boost::json::value json = boost::json::parse(msg); if (!json.is_object()) { std::cerr << "Invalid JSON object" << std::endl; return; } auto obj = json.as_object(); auto type = obj.at("type").as_string(); auto param1 = obj.at("param1").as_string(); int64_t param2 = 0; auto param2_it = obj.find("param2"); if (param2_it != obj.end()) { param2 = param2_it->value().as_int64(); } // 输出部分同上 }
方法三:捕获异常处理
若不想提前检查,也可以直接捕获at()抛出的异常,处理键缺失的情况:
void checkMessage(std::string msg) { boost::json::value json = boost::json::parse(msg); if (!json.is_object()) { std::cerr << "Invalid JSON object" << std::endl; return; } auto obj = json.as_object(); auto type = obj.at("type").as_string(); auto param1 = obj.at("param1").as_string(); int64_t param2 = 0; try { param2 = obj.at("param2").as_int64(); } catch (const std::out_of_range& e) { std::cerr << "param2 not present: " << e.what() << std::endl; } // 输出部分同上 }
更优实现:使用try_get()简化代码(Boost 1.75+)
Boost 1.75及以上版本提供了try_get()方法,可以直接尝试将指定键的值写入变量,成功返回true,失败返回false,代码更简洁:
void checkMessage(std::string msg) { boost::json::value json = boost::json::parse(msg); if (!json.is_object()) { std::cerr << "Invalid JSON object" << std::endl; return; } auto obj = json.as_object(); std::string type = obj.at("type").as_string(); std::string param1 = obj.at("param1").as_string(); int64_t param2 = 0; // 自动处理键不存在的情况,无需额外判断 obj.try_get(param2, "param2"); std::cout << "Received: " << std::endl; std::cout << "type: " << type << std::endl; std::cout << "param1: " << param1 << std::endl; std::cout << "param2: " << param2 << std::endl; }
注意事项
- 始终先判断JSON值是否为对象类型(
is_object()),避免as_object()抛出异常; - 对于业务上必须存在的键(如
type、param1),保留at()方法,确保键缺失时能快速抛出异常定位问题; - 对于可选键,根据场景选择上述安全取值方法,优先推荐
try_get()(版本支持时)或contains()。
内容的提问来源于stack exchange,提问作者Mendes
相关产品推荐
相关产品推荐

