C++使用Poco库封装一个HTTP客户端类

0x00 前言

我们在使用HTTP协议获取接口数据时,通常需要在Header和Query中添加参数,还有一种就是在Body中追加XML或者JSON格式的数据。本文主要讲述使用Poco库提交HTTP Post请求的Body中附加XML格式的数据,JSON格式的数据类似。

0x01 HttpClient类

#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H

#include <string>
#include <map>
#include <Poco/URI.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPCredentials.h>
#include <Poco/StreamCopier.h>
#include <Poco/NullStream.h>
#include <Poco/Exception.h>

class HttpClient
{
public:
    HttpClient(const std::string &host, const std::string &port = "80");

    std::string Get(const std::string &path,
                    const std::map<std::string, std::string> &header = std::map<std::string, std::string>());

    std::string Post(const std::string &path,
                     const std::string &body,
                     const std::map<std::string, std::string> &header = std::map<std::string, std::string>());

    bool DoRequest(Poco::Net::HTTPClientSession &session,
                   Poco::Net::HTTPRequest &request,
                   Poco::Net::HTTPResponse &response,
                   std::string &responseMsg);

    bool DoRequest(Poco::Net::HTTPClientSession &session,
                   Poco::Net::HTTPRequest &request,
                   Poco::Net::HTTPResponse &response,
                   const std::string &requestBody,
                   std::string &responseMsg);

private:
    std::string m_host;
    std::string m_port;
};

#endif // HTTPCLIENT_H

#include "httpclient.h"
#include <sstream>

HttpClient::HttpClient(const std::string &host, const std::string &port)
    : m_host(host), m_port(port)
{
}

std::string HttpClient::Get(const std::string &path,
                            const std::map<std::string, std::string> &header)
{
    try
    {
        Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));

        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
        // 设置请求头
        request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
        for (auto item : header)
        {
            request.set(item.first, item.second);
        }

        Poco::Net::HTTPResponse response;

        std::string retMsg;
        if (DoRequest(session, request, response, retMsg))
        {
            printf("%s\n", retMsg.c_str());
        }
        return retMsg;
    }
    catch (const Poco::Exception &ex)
    {
        printf("%s\n", ex.displayText().c_str());
    }

    return "";
}

std::string HttpClient::Post(const std::string &path,
                             const std::string &body,
                             const std::map<std::string, std::string> &header)
{
    try
    {
        Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));

        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
        // 设置请求头
        request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
        for (auto item : header)
        {
            request.set(item.first, item.second);
        }

        // XML类型的请求体
        // request.setContentType("application/xml");
        // request.setContentLength(body.length());

        Poco::Net::HTTPResponse response;

        std::string retMsg;
        if (DoRequest(session, request, response, body, retMsg))
        {
            printf("%s\n", retMsg.c_str());
        }
        return retMsg;
    }
    catch (const Poco::Exception &ex)
    {
        printf("[%s:%d] %s\n", __FILE__, __LINE__, ex.displayText().c_str());
    }

    return "";
}

bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
                           Poco::Net::HTTPRequest &request,
                           Poco::Net::HTTPResponse &response,
                           std::string &repMsg)
{

    session.sendRequest(request);                         // 发送请求
    std::istream &is = session.receiveResponse(response); // 接收响应
    std::ostringstream oss;
    printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());

    if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
    {
        // Poco::StreamCopier::copyStream(rs, std::cout);
        Poco::StreamCopier::copyStream(is, oss);
        if (!oss.str().empty())
        {
            // printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
            repMsg = oss.str();
        }

        return true;
    }
    else
    {
        printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
        Poco::NullOutputStream null;
        Poco::StreamCopier::copyStream(is, null);
        return false;
    }
}

bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
                           Poco::Net::HTTPRequest &request,
                           Poco::Net::HTTPResponse &response,
                           const std::string &requestBody,
                           std::string &responseMsg)
{
    std::ostream &os = session.sendRequest(request); // 发送请求
    // 添加请求体
    os << requestBody;

    std::istream &is = session.receiveResponse(response); // 接收响应
    std::ostringstream oss;
    printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());

    if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
    {
        // Poco::StreamCopier::copyStream(rs, std::cout);
        Poco::StreamCopier::copyStream(is, oss);
        if (!oss.str().empty())
        {
            // printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
            responseMsg = oss.str();
        }

        return true;
    }
    else
    {
        printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
        Poco::NullOutputStream null;
        Poco::StreamCopier::copyStream(is, null);
        return false;
    }
}

0x02 使用方法

在这里插入图片描述

0x04 代码说明

  1. HttpClient类中Post函数可以将请求头中"content-type"设置成application/xml,表示请求体的数据格式为XML,如果设置成application/json,,则发送的请求体的数据格式为JSON,在发送请求后追加上请求体数据。
  2. Poco库中的Poco::Net::HTTPClientSession类在使用sendRequest后获取的std::ostream流中去追加请求体数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/753209.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

禹神electron学习~

最近时间比较富裕 咱们浅浅来学习下electron 视频在这禹神&#xff1a;一小时快速上手Electron&#xff0c;前端Electron开发教程_哔哩哔哩_bilibili 先看下流程模型 先决条件 首先第一步 查看你的node和npm版本 创建你的应用 创建一个文件夹 我创建的名称为my-electron-…

人工智能期末复习思维导图,参考人工智能及其应用(第6版)和柴玉梅老师教材

其中第一、六、七、八、九章不用重点看&#xff0c;计算题一般会考1.语义网络、谓词逻辑&#xff0c;2.可信度&#xff0c;3.主观贝叶斯&#xff0c;4.一般合一置换&#xff0c;5.证据理论&#xff0c;6.盲目搜索。 第一章&#xff1a;绪论 第二章&#xff1a;知识表示方法 第…

MQ - RabbitMQ、SpringAMQP --学习笔记

什么是MQ&#xff1f; MQ 是消息队列&#xff08;Message Queue&#xff09;的缩写&#xff0c;它是一种应用程序间异步通信的技术。消息队列允许应用程序或服务间通过发送消息来交换数据&#xff0c;而不是直接调用对方&#xff0c;从而实现解耦、异步处理和负载均衡等目的。…

无需高配置 怎么获得超流畅的VR体验?

传统VR眼镜在使用中存在一些显著不足&#xff0c;而实时渲染技术又是如何解决的&#xff1f;接下来与大家共同探讨遇到的问题以及实时渲染在VR眼镜中的实际应用。 1、高配置要求 目前主流VR一体机的眼镜需要较高配置才能运行普通VR内容&#xff0c;且受限于VR眼镜的算力限制&…

工作纪实51-手撸AB实验分流策略

前几天写了一篇关于哈希算法的文章&#xff0c;起源就是在构思AB实验平台的时候&#xff0c;用到了哈希&#xff0c;所以对其做了深入的了解 AB实验平台是一般互联网做策略、样式实验会用到的一个系统&#xff0c;一般开启某个实验之后&#xff0c;需要对线上流量进行分流&…

太速科技-FMC144 -八路 250MSPS 14bit AD FMC子卡

FMC144 -八路 250MSPS 14bit AD FMC子卡 一、板卡概述   FMC144是一款具有8通道模数转换器&#xff08;ADC&#xff09;的FMC卡&#xff0c;具有14bit分辨率&#xff0c;最大采样速率达250Msps。时钟配置芯片为AD9516-1&#xff0c;可由板载10MHz时钟提供参考&#xff0c;也可…

[游戏开发][UE5]引擎学习记录

C Log和蓝图Log C Log 方法 UE_Log(参数1&#xff0c;参数2&#xff0c;参数3) //举例: UE_LOG(LogTemp, Error, TEXT("Log Info: %s"),"Test Log"); 三个参数的作用 参数1&#xff1a;输出窗口归类使用&#xff0c;你写什么它就显示什么 参数2&#x…

node.js安装

下载地址 https://nodejs.org/en/download 安装教程

Stable Diffusion初体验——提示词指南

前言 Stable Diffusion是一种深度学习模型&#xff0c;它能够根据提示词生成高质量的图像。在Stable Diffusion模型中&#xff0c;提示词起着至关重要的作用&#xff0c;因为它们为模型提供了关于所需输出的指导。本文将探讨Stable Diffusion关于提示词的原理&#xff0c;包括…

k8s集群node节点加入失败

出现这种情况&#xff1a; [preflight] FYI: You can look at this config file with kubectl -n kube-system get cm kubeadm-config -o yaml [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kub…

计算机网络——数据链路层(数据链路层概述及基本问题)

链路、数据链路和帧的概念 数据链路层在物理层提供服务的基础上向网络层提供服务&#xff0c;其主要作用是加强物理层传输原始比特流的功能&#xff0c;将物理层提供的可能出错的物理连接改造为逻辑上无差错的数据链路&#xff0c;使之对网络层表现为一条无差错的链路。 链路(…

sheng的学习笔记-AI-K均值算法

ai目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 需要学习前置知识&#xff1a;聚类&#xff0c;可参考 sheng的学习笔记-聚类(Clustering)-CSDN博客 目录 什么是k均值算法 流程 伪代码 数据集 伪代码 代码解释 划分示意图 优化目标 随机初始化 选择聚类数…

酣客的“FFC模式”|白酒商业模式|分润制度顶层架构设计

酣客公社摒弃传统商业模式&#xff0c;提出“心联网”及“FFC模式”的商业模式。 坐标&#xff1a;厦门&#xff0c;我是肖琳 深耕社交新零售行业10年&#xff0c;主要提供新零售系统工具及顶层商业模式设计、全案策划运营陪跑等。 今天和大家分享“酣客”的营销模式&#xff…

Parallels Toolbox for mac(pd工具箱) 6.0.2激活版

Parallels Toolbox 是由 Parallels 公司开发的一款实用工具集合软件&#xff0c;它主要面向使用 Parallels Desktop 的用户&#xff0c;提供了许多方便用户在 macOS 和 Windows 之间进行切换和管理的工具。Parallels Desktop 是一款流行的虚拟化软件&#xff0c;允许用户在 mac…

【24医学顶刊】GANDALF:主动学习 + 图注意力变换器 + 变分自编码器,改善多标签图像分类

GANDALF&#xff1a;主动学习 图注意力变换器 变分自编码器&#xff0c;改善多标签图像分类 提出背景子解法1&#xff1a;多标签信息样本的选择子解法2&#xff1a;生成信息丰富且非冗余的合成样本 例子&#xff1a;胸部X射线图像分析传统方法的操作和局限GaNDLF方法的优势 工…

理解ABP的领域驱动设计

大家好&#xff0c;我是张飞洪&#xff0c;感谢您的阅读&#xff0c;我会不定期和你分享学习心得&#xff0c;希望我的文章能成为你成长路上的垫脚石&#xff0c;让我们一起精进。 关于玩转ABP框架相关的文章&#xff0c;之前在博客园陆续写了《ABP vNext系列文章和视频》&…

电路仿真王者之争:SmartEDA如何领跑业界,打破传统仿真软件格局?

在电子设计领域&#xff0c;电路仿真软件一直扮演着至关重要的角色。它们为工程师们提供了一个虚拟的实验室&#xff0c;可以在不耗费大量实际资源的情况下&#xff0c;进行电路设计、优化和测试。在众多电路仿真软件中&#xff0c;SmartEDA以其独特的优势&#xff0c;逐渐崭露…

嵌入式开发十九:SysTick—系统定时器

在前面实验中我们使用到的延时都是通过SysTick进行延时的。 我们知道&#xff0c;延时有两种方式&#xff1a;软件延时&#xff0c;即CPU 循环等待产生的&#xff0c;这个延时是不精确的。第二种就是滴答定时器延时&#xff0c;本篇博客就来介绍 STM32F4 内部 SysTick 系统定时…

浅谈API生态建设:API安全策略的6项原则

API作为连接系统与应用的桥梁&#xff0c;在助力实现高效业务流程的同时&#xff0c;也不可避免出现资产管理困难、敏感数据泄漏风险骤增等安全问题。前段时间&#xff0c;安全公司Fastly公布了一项重磅调查报告&#xff0c;报告中显示95%的企业在过去1年中遭遇过API安全问题。…

AXI接口简介

AXI接口&#xff0c;全称为Advanced eXtensible Interface&#xff0c;是ARM公司推出的一种高性能、低成本、可扩展的高速总线接口。AXI接口是ARM公司提出的AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;高级微控制器总线架构的一部分。2003年发布了…