C++使用Poco库封装一个HTTP客户端类--Query参数

news2024/10/5 13:06:40

0x00 概述

我们使用Poco库的 Poco::Net::HTMLForm 类可以轻松实现表单数据的提交。


0x01 ApiPost提交表单数据

在这里插入图片描述


0x02 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/Net/HTMLForm.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>());

    // 在Query中添加表单数据
    std::string Post(const std::string &path,
                     const std::map<std::string, std::string> &query = std::map<std::string, std::string>(),
                     const std::map<std::string, std::string> &header = std::map<std::string, std::string>());

    // 在Body中使用JSON或XML数据
    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,
                   Poco::Net::HTMLForm &Query,
                   std::string &responseMsg);

    bool DoRequest(Poco::Net::HTTPClientSession &session,
                   Poco::Net::HTTPRequest &request,
                   Poco::Net::HTTPResponse &response,
                   const std::string &Body,
                   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::map<std::string, std::string> &query,
                             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);
        }

        // 设置请求参数
        Poco::Net::HTMLForm formQuery;
        for (auto item : query)
        {
            formQuery.add(item.first, item.second);
        }
        formQuery.prepareSubmit(request);

        Poco::Net::HTTPResponse response;

        std::string retMsg;
        if (DoRequest(session, request, response, formQuery, 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 "";
}

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,
                           Poco::Net::HTMLForm &Query,
                           std::string &responseMsg)
{
    std::ostream &os = session.sendRequest(request); // 发送请求
    // 添加请求参数
    Query.write(os);
    os.flush();

    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;
    }
}

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

    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;
    }
}

0x03 使用方法

#include <iostream>
#include <memory>
#include "httpclient.h"
using namespace std;

int main()
{
    std::unique_ptr<HttpClient> httpCli(new HttpClient("localhost", "18080"));

    std::map<std::string, std::string> header{{"content-type", "application/x-www-form-urlencoded"}};

    // localhost:18080?name=admin&password=admin&gender=male&subscribe=on
    std::map<std::string, std::string> query{{"name", "admin"},
                                             {"password", "admin"},
                                             {"gender", "male"},
                                             {"subscribe", "on"}};
    // 提交表单数据
    httpCli->Post("/", query, header);

    cout << "==Over==" << endl;
    return 0;
}

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

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

相关文章

set的应用(C++)

set的使用 【基本用法】 大家可以敲一下这段代码体会一下set的基本初始化和使用 #include <iostream> #include <set> #include <vector> using namespace std;int main() {set<int> st1; // 空的set// 使用迭代器构造string str("abcdef"…

【机器学习】基于密度的聚类算法:DBSCAN详解

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 基于密度的聚类算法&#xff1a;DBSCAN详解引言DBSCAN的基本概念点的分类聚类过…

Flower花所:稳定运营的数字货币交易所

Flower花所是一家稳定运营的数字货币交易所&#xff0c;致力于为全球用户提供安全、高效的数字资产交易服务。作为一家长期稳定运营的数字货币交易平台&#xff0c;Flower花所以其可靠的技术基础和优质的客户服务而闻名。 平台稳定性与可靠性&#xff1a; 持续运营&#xff1a;…

深度网络现代实践 - 深度前馈网络之反向传播和其他的微分算法篇

序言 反向传播&#xff08;Backpropagation&#xff0c;简称backprop&#xff09;是神经网络训练过程中最关键的技术之一&#xff0c;尤其在多层神经网络中广泛应用。它是一种与优化方法&#xff08;如梯度下降法&#xff09;结合使用的算法&#xff0c;用于计算网络中各参数的…

WordPress子比主题美化文章顶部添加百度收录按钮

要在WordPress子主题中美化文章顶部并添加百度收录按钮&#xff0c;你可以按照以下步骤操作&#xff1a; 首先&#xff0c;确保你的主题支持自定义CSS。如果不支持&#xff0c;你需要在主题目录下创建一个名为style.css的文件&#xff0c;并将以下代码复制到该文件中。如果你的…

Science期刊政策反转:允许生成式AI用于论文写作,意味着什么?

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 关于各大top期刊和出版社对于生成式AI用于论文写作中的规定&#xff0c;娜姐之前写过一篇文章&#xff1a; 如何合理使用AI写论文&#xff1f;来看Top 100学术期刊和出版社的…

高算力智能监控方案:基于瑞芯微RK3576核心板开发NVR网络视频录像机

近年来&#xff0c;随着人工智能和物联网技术的不断发展&#xff0c;网络视频录像机&#xff08;NVR&#xff09;在智能监控领域中的应用越来越广泛。本文将围绕RK3576核心板展开讨论&#xff0c;探讨其在NVR开发中的潜力和优势。 一、RK3576核心板 RK3576是瑞芯微的新一代中…

刷题之多数元素(leetcode)

多数元素 哈希表解法&#xff1a; class Solution { public:/*int majorityElement(vector<int>& nums) {//map记录元素出现的次数&#xff0c;遍历map&#xff0c;求出出现次数最多的元素unordered_map<int,int>map;for(int i0;i<nums.size();i){map[nu…

【星海随笔】ssh全解

发现 ssh 把我卡了很久&#xff0c;自己的文档也没有专门写 ssh 的&#xff0c;这一个文档会持续专精更新 ssh 相关的技术文档。 有些企业是全 BMC 管理平台。没有 ssh 密码登录权限 sudo apt-get install openssh-server检查SSH配置文件&#xff08;通常是 /etc/ssh/sshd_conf…

干货 | 2024云安全责任共担模型(免费下载)

以上是资料简介和目录&#xff0c;如需下载&#xff0c;请前往星球获取&#xff1a;

制定事件响应计划的四个关键步骤,如何做到风险闭环

一个有效的安全事件响应策略的关键组成部分有哪些&#xff1f;一个有效的安全事件响应策略包括四个关键组成部分&#xff0c;它们协同工作以确保对网络安全问题的快速和有效响应。 一个有效的安全事件响应策略的关键组成部分有哪些&#xff1f; 一个有效的安全事件响应策略包括…

HTML5使用<details>标签:展开/收缩信息

details 标签提供了一种替代 JavaScript 的方法&#xff0c;它主要是提供了一个展开/收缩区域。details 标签中可以使用 summary 标签从属于 details 标签&#xff0c;单击 summary 标签中的内容文字时&#xff0c;details 标签中的其他所有从属元素将会展开或收缩。语法如下&a…

职升网:详细分析!中级统计师考试题型和分值情况!

中级统计师考试题型及分值有&#xff1a;单选题&#xff1a;40道题&#xff0c;每题1分&#xff0c;共40分;多选题&#xff1a;15道题&#xff0c;每题2分&#xff0c;共30分;判断题&#xff1a;20道题&#xff0c;每题1分&#xff0c;共20分;综合应用题&#xff1a;15道题&…

视觉语言模型:融合视觉与语言的未来

1. 概述 视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;是能够同时处理和理解视觉&#xff08;图像&#xff09;和语言&#xff08;文本&#xff09;两种模态信息的人工智能模型。这种模型结合了计算机视觉和自然语言处理的技术&#xff0c;使得它们能够在…

Arthas实战(5)- 项目性能调优

1、接口耗时查询&#xff1a;trace命令 trace 命令能主动搜索 class-pattern&#xff0f;method-pattern 对应的方法调用路径&#xff0c;渲染和统计整个调用链路上的所有性能开销和追踪调用链路。 1.1 准备测试应用 新建一个 SpringBoot 应用&#xff0c;写一耗时久的代码&…

蜂窝物联农业气象站,守护丰收每一步

现代农业的革新者——农业自动气象站&#xff0c;正以其多功能的传感器、高效的数据采集传输系统、智能的数据云平台以及可靠的供电供网系统&#xff0c;成为农业生产中的得力助手。这些传感器能够实时监测温度、湿度、风速、风向、气压、土壤温度、土壤湿度、土壤PH值、土壤盐…

JDK新特性之协程

在 JVM 中&#xff0c;java 线程直接映射内核线程&#xff0c;因此 java 线程的创建、销毁和调度都要依赖内核态的操作&#xff08;系统调用&#xff09;。而协程是真正的用户线程&#xff0c;如上图所示很多的协程可以映射很少的几个内核线程&#xff0c;并且协程的创建、销毁…

树模型详解2-GBDT算法

与adaboost一样&#xff0c;GBDT也是采用前向分步算法&#xff0c;只是它会用决策树cart算法作为基学习器&#xff0c;因此先要从分类树和回归树讲起 决策树-提升树-梯度提升树 决策树cart算法 回归树&#xff1a;叶子结点的值是所有样本落在该叶子结点的平均值 如何构建&a…

NTP协议格式解析

1. NTP时间戳格式 SNTP使用在RFC 1305 及其以前的版本所描述标准NTP时间戳的格式。与因特网标准标准一致&#xff0c; NTP 数据被指定为整数或定点小数&#xff0c;位以big-endian风格从左边0位或者高位计数。除非不这样指定&#xff0c;全部数量都将设成unsigned的类型&#…