C++ 使用 curl 发送 json 数据请求

本文介绍如何利用curl库与nlohmann/json库实现客户端与服务器之间的JSON数据交换,具体步骤包括将Person对象转化为JSON字符串发送,服务器接收处理后返回用户喜欢的语言,最后客户端解析响应获取相关信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用到的库:

假设现在 Client 想要获取 Person 喜欢的语言,需要发送 Person 的个人信息到 Server,Server 根据用户姓名返回他喜欢的语言。

struct Book {
  std::string name;
};

struct Person {
  std::string name;
  int age;
  std::vector<Book> favoriteBooks;
};

struct FavoriteLanguage {
  std::string name;
  std::vector<std::string> languages;
};

这个过程需要三个处理步骤:
- Client 将 Person 信息转为 json,并通过 curl 发送出去
- Server 收到数据后解 json 处理并返回该 Person 喜欢的语言
- Client 收到 Response 后解 json 得到喜欢的语言

Book 转 json:

void to_json(json &j, const Book &book) {
  j = {
      {"name", book.name}
  };
}

Person 转 json:

void to_json(json &j, const Person &p) {
  j = {
      {"name", p.name},
      {"age", p.age}
  };
  if (!p.favoriteBooks.empty())
    j.push_back({"books", p.favoriteBooks});
}
Person p{"Aland", 18, books};
json j = p; // Person 转 json
std::string dump = j.dump();

通过 curl 发送 http POST 请求,数据为 json 格式。

std::string url = "127.0.0.1:9999/favorbooks";
CURL *curl;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L); // POST
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, dump.c_str()); // 要发送的数据
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); // 处理 response 的回调函数
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &favor); // 存储返回的结果

curl_easy_perform(curl);
curl_easy_cleanup(curl);

Client 解析返回的 response:

static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userp) {
  size_t realsize = size * nmemb;
  auto j = json::parse(std::string((char *) ptr));
  FavoriteLanguage *favor = (FavoriteLanguage *) userp;
  *favor = j; // json 转 FavoriteLanguage
  return realsize;
}

json 转结构体:

void from_json(const json &j, FavoriteLanguage &favor) {
  favor.name = j["name"];
  favor.languages = j["languages"].get<std::vector<std::string>>();
}

解析后的打印结果:

{"age":18,"books":[{"name":"TCP/IP Illustrated, Volume 1"},{"name":"Advanced Programming in the UNIX Environment"}],"name":"Aland"}
{"languages":["C++","Golang","Python"],"name":"Aland"}
Name:Aland
Languages:
  C++
  Golang
  Python

注: 详细代码见 https://github.com/alandtsang/cppdemo/tree/master/src/curljson

遇到的错误

could not find to_json() method in T's namespace

这个问题通常是两点引起的(下列解法对to_jsonfrom_json 都适用):

  • 没有对要转换的结构体做 to_json 转换。
  • 外层结构体做了 to_json 转换,但是结构体包含的结构体没有做 to_json 转换。

参考

C libcurl get output into a string

creating nested json object in c++ using nlohmann json

Unable to locate ‘to_json()’ and ‘from_json()’ methods in the same namespace

Why not also look inside the type for (static) to_json and from_json funtions?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值