如何使用C++ REST SDK(Casablanca)提取API返回的特定JSON数据
嘿,恭喜你已经能拿到API返回的完整JSON啦!提取特定数据其实很简单,cpprestsdk(Casablanca)本身就提供了一套方便的JSON解析工具,我来给你一步步讲清楚~
核心思路
cpprestsdk里处理JSON的核心类是web::json::value,你只需要把HTTP响应转换成这个对象,然后就可以像操作普通键值对一样提取你需要的字段了。
具体步骤&代码示例
假设你的API返回的JSON长这样(举个例子):
{ "id": 123, "title": "cpprestsdk入门", "author": { "name": "张三", "email": "zhangsan@example.com" }, "tags": ["C++", "REST API", "Casablanca"] }
我们基于你的现有代码,添加解析逻辑:
1. 先把HTTP响应转换成JSON对象
在你拿到http_response之后,先执行这行代码获取JSON对象:
web::json::value json_response = response.extract_json().get();
2. 提取不同类型的字段
提取整数/数字字段(比如id)
// 先检查字段是否存在,避免报错 if (json_response.has_field(U("id"))) { int article_id = json_response.at(U("id")).as_integer(); std::cout << "文章ID: " << article_id << std::endl; }
提取字符串字段(比如title)
注意cpprestsdk用的是宽字符串,所以要用std::wcout输出:
if (json_response.has_field(U("title"))) { utility::string_t article_title = json_response.at(U("title")).as_string(); std::wcout << L"文章标题: " << article_title << std::endl; }
提取嵌套对象里的字段(比如author下的name)
如果字段是嵌套的JSON对象,先拿到子对象再提取:
if (json_response.has_field(U("author"))) { web::json::value author_obj = json_response.at(U("author")); if (author_obj.has_field(U("name"))) { utility::string_t author_name = author_obj.at(U("name")).as_string(); std::wcout << L"作者姓名: " << author_name << std::endl; } }
提取数组字段(比如tags)
数组可以转换成web::json::array,然后遍历获取元素:
if (json_response.has_field(U("tags"))) { web::json::array tags_array = json_response.at(U("tags")).as_array(); std::wcout << L"标签列表:" << std::endl; for (const auto& tag : tags_array) { std::wcout << L"- " << tag.as_string() << std::endl; } }
3. 异常处理(可选但推荐)
如果直接用at()访问不存在的字段,会抛出web::json::json_exception异常,你可以用try-catch来捕获:
try { utility::string_t title = json_response.at(U("title")).as_string(); std::wcout << L"文章标题: " << title << std::endl; } catch (const web::json::json_exception& e) { std::cerr << "访问title字段出错: " << e.what() << std::endl; }
整合到你的代码里
把这些逻辑放到你处理响应的回调里就行,比如:
#include "stdafx.h" #include <iostream> #include <cpprest/http_client.h> #include <cpprest/filestream.h> using namespace utility; using namespace web::http; using namespace web::http::client; using namespace web::json; void call_api() { http_client client(U("https://你的API地址")); client.request(methods::GET) .then([](http_response response) { if (response.status_code() == status_codes::OK) { // 获取JSON对象 value json_response = response.extract_json().get(); // 这里添加你需要的字段提取逻辑 if (json_response.has_field(U("title"))) { string_t title = json_response.at(U("title")).as_string(); std::wcout << L"提取到标题: " << title << std::endl; } } else { std::cerr << "请求失败,状态码: " << response.status_code() << std::endl; } }) .wait(); } int main() { call_api(); return 0; }
小提示
- 字符串字段要用
U("字段名")来构造宽字符串字面量,和cpprestsdk的类型匹配 - 输出宽字符串要用
std::wcout,如果用std::cout会显示乱码或者错误 - 不同类型的字段要调用对应的
as_xxx()方法,比如字符串用as_string(),整数用as_integer(),布尔用as_bool()
内容的提问来源于stack exchange,提问作者noyruto88




