You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何使用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

火山引擎 最新活动