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

news2024/10/6 1:03:26

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流中去追加请求体数据。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zuul介绍

Zuul 是 Netflix 开源的一个云平台网络层代理&#xff0c;它主要用于路由、负载均衡、中间件通信和动态路由。Zuul 本质上是一个基于 JVM 的网关&#xff0c;它提供了以下功能&#xff1a; 1.路由&#xff1a;Zuul 允许客户端和服务器之间的所有入站和出站请求通过一个中心化的…

Hadoop页面报错Permission denied: user=dr.who, access....

1、临时解决 hdfs dfs -chmod -R 777 /这种方法&#xff0c;存在一个不足&#xff0c;就是后面重新创建的文件夹&#xff0c;页面进行删除的时候&#xff0c;依然报这个错。 但是&#xff0c;对于应付紧急客户需求&#xff0c;可以临时用一下。 2、永久解决 查看页面的Owner…

超声波清洗机怎么选?极力推荐四款口碑大牌超声波清洗机

相信大家都知道超声波清洗机&#xff0c;每次眼镜脏的时候&#xff0c;去眼镜店里让老板帮忙清洗&#xff0c;她们用的就是超声波清洗机&#xff0c;通过超声波的原理深入物品深处清洁&#xff0c;清洁效果非常好。相对手洗的方式&#xff0c;超声波清洗机能够保护镜片在清洗过…

SpringCloud_Ribbon负载均衡

概述 SpringCloud底层其实是利用了一个名为Ribbon的组件&#xff0c;来实现负载均衡功能的。 源码 LoadBalancerInterceptor 其中含有intercept方法&#xff0c;拦截用户的HttpRequest请求&#xff1a; request.getURI() 获取请求uri&#xff0c;即http://userservice/use…

【哈哈大一上学的全忘了,重开!!】STM32从零入门物联网开发

本笔记资料来源 &#xff1a;STM32物联网入门30步&#xff1d;单片机物联网入门教程 WIFI连接阿里云物联网CubeMXHAL库蓝牙ESP8266杜洋主讲_哔哩哔哩_bilibili IOT&#xff1a;Internet of things 学习目标&#xff1a; 1.掌握洋桃IoT开发板的各功能以及驱动与基本应用 2.掌…

Python容器 之 字符串--字符串的常用操作方法

1.字符串查找方法 find() 说明&#xff1a;被查找字符是否存在于当前字符串中。 格式&#xff1a;字符串.find(被查找字符) 结果&#xff1a;如果存在则返回第一次出现 被查找字符位置的下标 如果不存在则返回 -1 需求&#xff1a; 1. 现有字符串数据: 我是中国人 2. 请设计程序…

vue根据文字长短展示跑马灯效果

介绍 为大家介绍一个我编写的vue组件 auto-marquee &#xff0c;他可以根据要展示文本是否超出展示区域&#xff0c;来判断是否使用跑马灯效果&#xff0c;效果图如下所示 假设要展示区域的宽度为500px&#xff0c;当要展示文本的长度小于500px时&#xff0c;只会展示文本&…

mysql5.7.30忘记root密码

windows系统安装了mysql5.7.30&#xff0c;在使用navicat链接mysql时候&#xff0c;提示 如何解决&#xff1a; 打开任务管理器的服务&#xff0c;查看有没有MYSQL服务。 如果没有&#xff0c;则按照下面的csdn博客进行操作。 https://blog.csdn.net/clj198606061111/article…

PostgreSQL的学习心得和知识总结(一百四十七)|深入理解PostgreSQL数据库之transaction chain的使用和实现

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

Firewalld 概述

1.firewalld简介 firewalld的作用是为包过滤机制提供匹配规则(或称为策略),通过各种不同的规则&#xff0c;告诉 netfiter对来自指定源、前往指定目的或具有某些协议特征的数据包采取何种处理方式。 为了更加方便地组织和管理防火墙&#xff0c;firewalld 提供了支持网络区域…

【笔记】手工部署之linux中开放已安装的mysql与tomcat端口

在需要打包的springboot项目中输入mvn clean package 在target下面获得jar包 进入linux中你想要该jar包存在的位置 将jar包上传至linux中 此时在浏览器中输入linux的ip地址&#xff1a;端口号/mapping路径为404 故&#xff1a; 在linux中另开一个标签页 检查mysql和tomcat已…

JMH319【亲测整理】2017剑侠情缘2剑网2汉化版+网游VM单机版+修复纹饰翅膀+内置GM命令无限道具+一键端视频安装教学

资源介绍&#xff1a; 这一套新端早就在手上 一直没分享出来 既然大家放出来了 我也就发出来大家研究吧 目前在改另外一套 是否需要虚拟机&#xff1a;是 文件大小&#xff1a;压缩包约7G 支持系统&#xff1a;win7、win10、win11 硬件需求&#xff1a;运行内存12G …

遇到多语言跨境电商系统源码问题?这里有解决方案!

从手机到电脑&#xff0c;从线下到线上&#xff0c;如今&#xff0c;跨境电商正在打破地域界限&#xff0c;成为全球贸易的新引擎。在这个全球化的背景下&#xff0c;跨境电商平台的运营也面临着一系列的挑战&#xff0c;其中之一就是多语言问题。如果你遇到了多语言跨境电商系…

c进阶篇(三):字符串函数

1.strlen: strlen - C Reference strlen 函数是一个标准库函数&#xff0c;用于计算以 null 结尾的字符串的长度&#xff0c;也就是字符串中实际字符的数量&#xff0c;不包括最后的 null 终止符 \0。它定义在 <string.h> 头文件中。 函数原型:size_t strlen(const ch…

PyCharm 著名编程利器下载安装:Python开发者的必备神器!

PyCharm&#xff0c;它不仅拥有卓越的性能&#xff0c;更以其丰富多样的功能和工具&#xff0c;让开发者在 Python 项目的开发中事半功倍&#xff0c;无论是 Web 开发、科学计算&#xff0c;还是数据分析等领域&#xff0c;都能轻松应对。 在代码编辑方面&#xff0c;PyCharm 的…

C#中的时间数据格式化详解与应用示例

文章目录 1、基本概念基本格式化方法 2、实用的时间格式化方法格式化日期格式化时间格式化时间戳解析日期时间字符串 3、实际应用4、应用示例结论 在软件开发中&#xff0c;时间数据是无处不在的。无论是用户登录时间、数据备份时间&#xff0c;还是日志记录&#xff0c;都需要…

嵌入式学习——硬件(IIC、ADC)——day56

1. IIC 1.1 定义&#xff08;同步串行半双工通信总线&#xff09; IIC&#xff08;Inter-Integrated Circuit&#xff09;又称I2C&#xff0c;是是IICBus简称&#xff0c;所以中文应该叫集成电路总线。是飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备…

Pytorch实战(二)

文章目录 前言一、LeNet5原理1.1LeNet5网络结构1.2LeNet网络参数1.3LeNet5网络总结 二、AlexNext2.1AlexNet网络结构2.2AlexNet网络参数2.3Dropout操作2.4PCA图像增强2.5LRN正则化2.6AlexNet总结 三、LeNet实战3.1LeNet5模型搭建3.2可视化数据3.3加载训练、验证数据集3.4模型训…

在 Postman 中使用 Body 进行 POST 请求

Postman 是开发者日常工具箱中不可缺少的一部分&#xff0c;特别是在 API 开发和调试环节中。 为什么使用 POST 请求 POST 请求用于向服务器发送数据&#xff0c;这些数据通常被处理后存储。与 GET 请求不同&#xff0c;POST 请求将数据嵌入请求体&#xff08;Body&#xff0…

最细最有条理解析:事件循环(消息循环)是什么?进程与线程的定义、关系与差异

目录 事件循环&#xff1a;引入 一、浏览器的进程模型 1.1、什么是进程&#xff08;Process&#xff09; 1.2、什么是线程&#xff08;Thread&#xff09; 1.3、进程与线程之间的关系联系与区别 二、浏览器有哪些进程和线程 2.1、浏览器的主要进程 ①浏览器进程 ②网络…