C++通过HTTP请求Get或Post方式请求Json数据

2023-05-16

转载:C++通过HTTP请求Get或Post方式请求Json数据
最近在工作中,由于合作商只提供uRL,我这边需要通过HTTP请求Get或Post方式请求Json数据,然后解析JSON格式,解析json我使用的第三方库jsoncpp,代码如下

#pragma once
#include <iostream>
#include <windows.h>
#include <wininet.h>

using namespace std;

//每次读取的字节数
#define READ_BUFFER_SIZE        4096

enum HttpInterfaceError
{
    Hir_Success = 0,        //成功
    Hir_InitErr,            //初始化失败
    Hir_ConnectErr,            //连接HTTP服务器失败
    Hir_SendErr,            //发送请求失败
    Hir_QueryErr,            //查询HTTP请求头失败
    Hir_404,                //页面不存在
    Hir_IllegalUrl,            //无效的URL
    Hir_CreateFileErr,        //创建文件失败
    Hir_DownloadErr,        //下载失败
    Hir_QueryIPErr,            //获取域名对应的地址失败
    Hir_SocketErr,            //套接字错误
    Hir_UserCancel,            //用户取消下载
    Hir_BufferErr,            //文件太大,缓冲区不足
    Hir_HeaderErr,            //HTTP请求头错误
    Hir_ParamErr,            //参数错误,空指针,空字符
    Hir_UnknowErr,
};
enum HttpRequest
{
    Hr_Get,
    Hr_Post
};
class CWininetHttp
{
public:
    CWininetHttp(void);
    ~CWininetHttp(void);

public:
    //  通过HTTP请求:Get或Post方式获取JSON信息 [3/14/2017/shike]
    const std::string RequestJsonInfo( const std::string& strUrl,
                                HttpRequest type = Hr_Get, 
                                 std::string lpHeader = "",
                                 std::string lpPostData = "");
protected:
    // 解析卡口Json数据 [3/14/2017/shike]
    void ParseJsonInfo(const std::string &strJsonInfo);

    // 关闭句柄 [3/14/2017/shike]
    void Release();

    // 释放句柄 [3/14/2017/shike]
    void ReleaseHandle( HINTERNET& hInternet );

    // 解析URL地址 [3/14/2017/shike]
    void ParseURLWeb( std::string strUrl, std::string& strHostName, std::string& strPageName, WORD& sPort);

    // UTF-8转为GBK2312 [3/14/2017/shike]
    char* UtfToGbk(const char* utf8);

private:
    HINTERNET            m_hSession;
    HINTERNET            m_hConnect;
    HINTERNET            m_hRequest;
    HttpInterfaceError    m_error;
};
/*************************************************
File name  :  WininetHttp.cpp
Description:  通过URL访问HTTP请求方式获取JSON
Author     :  shike
Version    :  1.0
Date       :  2016/10/27
Copyright (C) 2016 -  All Rights Reserved
*************************************************/
#include "WininetHttp.h"
//#include "Common.h"
#include <json/json.h>
#include <fstream>
#include "common/CVLog.h"
#pragma comment(lib, "Wininet.lib")
#include <tchar.h>
using namespace std;

extern CCVLog CVLog;

CWininetHttp::CWininetHttp(void):m_hSession(NULL),m_hConnect(NULL),m_hRequest(NULL)
{
}

CWininetHttp::~CWininetHttp(void)
{
    Release();
}

//  通过HTTP请求:Get或Post方式获取JSON信息 [3/14/2017/shike]
const std::string CWininetHttp::RequestJsonInfo(const std::string& lpUrl,
                                                HttpRequest type/* = Hr_Get*/,
                                                std::string strHeader/*=""*/,
                                                std::string strPostData/*=""*/)
{
    std::string strRet = "";
    try
    {
        if ( lpUrl.empty())
        {
            throw Hir_ParamErr;
        }
        Release();
        m_hSession = InternetOpen(_T("Http-connect"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL);    //局部

        if ( NULL == m_hSession )
        {
            throw Hir_InitErr;
        }

        INTERNET_PORT port    = INTERNET_DEFAULT_HTTP_PORT;
        std::string strHostName = "";
        std::string strPageName = "";

        ParseURLWeb(lpUrl, strHostName, strPageName, port);
        printf("lpUrl:%s,\nstrHostName:%s,\nstrPageName:%s,\nport:%d\n",lpUrl.c_str(),strHostName.c_str(),strPageName.c_str(),(int)port);

        m_hConnect = InternetConnectA(m_hSession, strHostName.c_str(), port, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);

        if ( NULL == m_hConnect )
        {
            throw Hir_ConnectErr;
        }

        std::string strRequestType;
        if ( Hr_Get == type )
        {
            strRequestType = "GET";
        }
        else
        {
            strRequestType = "POST";
        }

        m_hRequest = HttpOpenRequestA(m_hConnect,strRequestType.c_str(), strPageName.c_str(),"HTTP/1.1", NULL, NULL, INTERNET_FLAG_RELOAD, NULL);
        if ( NULL == m_hRequest )
        {
            throw Hir_InitErr;
        }

        DWORD dwHeaderSize = (strHeader.empty()) ? 0 : strlen(strHeader.c_str());
        BOOL bRet = FALSE;
        if ( Hr_Get == type )
        {
            bRet = HttpSendRequestA(m_hRequest,strHeader.c_str(),dwHeaderSize,NULL, 0);
        }
        else
        {
            DWORD dwSize = (strPostData.empty()) ? 0 : strlen(strPostData.c_str());
            bRet = HttpSendRequestA(m_hRequest,strHeader.c_str(),dwHeaderSize,(LPVOID)strPostData.c_str(), dwSize);
        }
        if ( !bRet )
        {
            throw Hir_SendErr;
        }

        char szBuffer[READ_BUFFER_SIZE + 1] = {0};
        DWORD dwReadSize = READ_BUFFER_SIZE;
        if ( !HttpQueryInfoA(m_hRequest, HTTP_QUERY_RAW_HEADERS, szBuffer, &dwReadSize, NULL) )
        {
            throw Hir_QueryErr;
        }
        if ( NULL != strstr(szBuffer, "404") )
        {
            throw Hir_404;
        }

        while( true )
        {
            bRet = InternetReadFile(m_hRequest, szBuffer, READ_BUFFER_SIZE, &dwReadSize);
            if ( !bRet || (0 == dwReadSize) )
            {
                break;
            }
            szBuffer[dwReadSize]='\0';
            strRet.append(szBuffer);
        }
    }
    catch(HttpInterfaceError error)
    {
        m_error = error;
    }
    return std::move(strRet);
}

// 解析Json数据 [11/8/2016/shike]
void CWininetHttp::ParseJsonInfo(const std::string &strJsonInfo)
{
    Json::Reader reader;                                    //解析json用Json::Reader
    Json::Value value;                                        //可以代表任意类型
    if (!reader.parse(strJsonInfo, value))  
    {  
        CVLog.LogMessage(LOG_LEVEL_ERROR,"[CXLDbDataMgr::GetVideoGisData] Video Gis parse data error...");
    }
    if (!value["result"].isNull())        
    {
        int nSize = value["result"].size();
        for(int nPos = 0; nPos < nSize; ++nPos)                //对数据数组进行遍历
        {
            //PGCARDDEVDATA stru ;
            //stru.strCardName        = value["result"][nPos]["tollgateName"].asString();
            //stru.strCardCode        = value["result"][nPos]["tollgateCode"].asString();
            //std::string strCDNum    = value["result"][nPos]["laneNumber"].asString();    //增加:车道总数
            //stru.nLaneNum            = atoi(strCDNum.c_str());
            //std::string strLaneDir    = value["result"][nPos]["laneDir"].asString();        //增加:车道方向,进行规则转换
            //stru.strLaneDir            = TransformLaneDir(strLaneDir);
            //stru.dWgs84_x            = value["result"][nPos]["wgs84_x"].asDouble();
            //stru.dWgs84_y            = value["result"][nPos]["wgs84_y"].asDouble();
            //stru.dMars_x            = value["result"][nPos]["mars_x"].asDouble();
            //stru.dMars_y            = value["result"][nPos]["mars_y"].asDouble();
            //lstCardDevData.emplace_back(stru);
        }
    }
}

// 解析URL地址 [3/14/2017/shike]
void CWininetHttp::ParseURLWeb( std::string strUrl, std::string& strHostName, std::string& strPageName, WORD& sPort)
{
    sPort = 80;
    string strTemp(strUrl);
    std::size_t nPos = strTemp.find("http://");
    if (nPos != std::string::npos)
    {
        strTemp = strTemp.substr(nPos + 7, strTemp.size() - nPos - 7);
    }

    nPos = strTemp.find('/');
    if ( nPos == std::string::npos )    //没有找到
    {
        strHostName = strTemp;
    }
    else
    {
        strHostName = strTemp.substr(0, nPos);
    }

    std::size_t nPos1 = strHostName.find(':');
    if ( nPos1 != std::string::npos )
    {
        std::string strPort = strTemp.substr(nPos1 + 1, strHostName.size() - nPos1 - 1);
        strHostName = strHostName.substr(0, nPos1);
        sPort = (WORD)atoi(strPort.c_str());
    }
    if ( nPos == std::string::npos )
    {
        return ;
    }
    strPageName = strTemp.substr(nPos, strTemp.size() - nPos);
}

// 关闭句柄 [3/14/2017/shike]
void CWininetHttp::Release()
{
    ReleaseHandle(m_hRequest); 
    ReleaseHandle(m_hConnect); 
    ReleaseHandle(m_hSession);
}

// 释放句柄 [3/14/2017/shike]
void CWininetHttp::ReleaseHandle( HINTERNET& hInternet )
{
    if (hInternet) 
    { 
        InternetCloseHandle(hInternet); 
        hInternet = NULL; 
    }
}

// UTF-8转为GBK2312 [3/14/2017/shike]
char* CWininetHttp::UtfToGbk(const char* utf8)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
    wchar_t* wstr = new wchar_t[len+1];
    memset(wstr, 0, len+1);
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
    char* str = new char[len+1];
    memset(str, 0, len+1);
    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
    if(wstr) delete[] wstr;
    return str;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++通过HTTP请求Get或Post方式请求Json数据 的相关文章

  • Alamofire:处理错误并返回成功响应

    嗨 我对 Alamofire 和 json 还很陌生 我只是想问如何处理成功响应的错误 下面是 api 对 post 请求的响应 data cabinet id 3289146811 created at 2018 04 11T04 53
  • 检查jsonPath中是否有重复的值

    我有一个 jsonPath 如下 book category reference author Nigel Rees title Sayings of the Century price 8 95 category fiction auth
  • Ruby 中的参数化 get 请求?

    如何创建 HTTPGETRuby 中带参数的请求 这很容易做到 当你POSTing require net http require uri HTTP post form URI parse http www example com sea
  • 使用 Struts 2.2.x 的简单 JSON 示例?

    我在获取 JSON 结果时遇到问题支柱2 2 1 1 http struts apache org 2 2 1 1 index html 有没有人有一个简单的工作示例 可以使用以下命令将 JSON 结果返回到 JSP支柱2 2 1 1并准备
  • 获取 QComboBox 的所有项目 - PyQt4 (Python)

    我有很多QComboBoxes 在某个时刻 我需要获取特定的每个项目QComboBox迭代 虽然我只能有一个与中的项目相对应的项目列表QComboBox 我宁愿直接从小部件本身获取它们 有大量的QComboBoxes每个都有很多项目 有没有
  • 使用 libGDX 写入 Json

    我是 Json 和 libGDX 的新手 但我创建了一个简单的游戏 我想将玩家姓名及其分数存储在 Json 文件中 有没有办法做到这一点 我想创建一个 Json 文件Gdx files localStorage如果它不存在 如果存在 则向其
  • 使用VBA抓取实时数据

    我想从中抓取实时数据https iboard ssi com vn bang gia hose https iboard ssi com vn bang gia hose使用VBA 我的代码如下 但它不会返回其中包含数据的 html 文件
  • 使用 Servlet 启动 VLC HTTP Stream 时出现问题

    我正在为自己开发一个 VLC 项目 我的目标是创建一个 HTML 前端来启动流 我通过使用 Java Servlet 来完成此操作 概述 乌班图13 04 Java 7 21 冰茶 2 3 9 Eclipse JAVAEE IDE 雄猫7
  • pyodbc 返回的行不可 JSON 序列化

    我正在尝试使用 Python 中的 pyodbc 库检索表的行 我能够成功检索表和表的字段 现在我有一个名为 apx roomtypes 的表 其数据如下 但是 当我将 pyodbc 行附加到列表 然后尝试将列表转储到 JSON 时 出现错
  • Symfony 4 和 Doctrine 2 从集合中删除(第一个)项目后序列化导致转换为 JSON 对象而不是数组

    我在序列化已删除第一个元素的集合时遇到很多麻烦 我有 CompaniesCollection 实体 与 Company 实体有 Many2Many 关系 ORM ManyToMany targetEntity App Entity Comp
  • 将 JSON 与嵌套数组和 json 进行比较(数组顺序无关紧要)

    你好 我正在尝试比较java中的两个json 每个键可以包含一个json对象或json对象数组 并且它们中的每个也可以是数组或json 这是 Json 的示例 id 123123asd123 attributes name apps val
  • 使用 PHP 将数据添加到 json

    我使用 json decode 创建一个 json 对象 在浏览了一些元素之后 我想向其中添加子元素 我该怎么做呢 取决于您传递给的选项json decode http php net manual en function json dec
  • 如何在highcharts中设置动态数据

    我正在从 servlet 获取数据 我从 servlet 发送的 json 对象的 sysout 是 jsonArray bugzilla 20 redmind 14 现在我的java脚本是
  • 组合类中的多态 lift-json 反序列化

    我正在尝试使用 Lift Json 自动将 json 对象反序列化为 scala 类 其中的坐标类用于存储 GeoJson 信息 case class Request name String geometry Geometry sealed
  • 如何在 PHP 中从serializeArray 获取 POST 值?

    我正在尝试这个我见过的新方法serializeArray with ajax var data form input serializeArray post var action process data data ajax etc 这样我
  • 请求响应后正文中出现奇怪的字符

    我正在使用 NodeJS 和 Request 来发布 JSON 并获取其中包含数据的结果 我使用 Postman 设置此请求 并获取完全可读的 JSON 数据 d type Qvision WoningenModule Lib aanbod
  • 如何发送/接收 JSON?

    我知道这是一个愚蠢的问题 但我通常不进行 Web 编程 并且被要求发送一些 JSON 数据并接收一些回报 我用谷歌搜索 很清楚如何编码和解码 JSON 数据 但我对此很陌生 我不知道如何与给定的 URL 进行通信并说 这里有一些数据 请发回
  • 在 Symfony2 中使用 json 数据水合实体

    有没有办法用 Symfony2 中传入请求的 json 数据来水合实体 我以为有类似的东西 Form bindRequest 但我找不到任何东西 如果能将这个功能与 knockout js 等库一起使用 那就太好了 如果您需要从 JSON
  • Next.js API 路由神秘地修改 JSON 负载

    由于某种原因 当我通过 Postman 作为原始文本发送 JSON 格式的数据时 没有任何问题 当我通过 Postman 发送与原始 JSON 完全相同的数据时 区别应该只是content type标头是application json代替
  • 使用 JsonWriter 时,WriteStartConstructor 的用途是什么?

    标题说明了一切 我看到它 及其相应的结尾 吐出以下内容 new Foo 但我不明白什么new实际上是在反序列化时执行的 文档只是说它编写了一个 Json 构造函数 但没有说 Json 构造函数是什么is 此方法是作为增强功能的一部分引入的

随机推荐

  • Linux 网络开发必学课程(七)UDP 数据收发实战、深入UDP 数据收发

    15 UDP 数据收发实战 再论 UDP 协议 UDP 是无连接的 不可靠的 xff0c 无应答消息 xff0c 数据包无序号标识 UDP 是面向数据包的 xff0c 对应用层数据既不合并也不拆分 xff08 保留数据包边界 xff0c 不
  • Java 删除非空文件夹

    Java中的File delete 方法只能删除文件或者空文件夹 xff0c 无法删除非空文件夹 xff0c 当是非空文件夹时 xff0c 方法返回false xff0c 下面写一个工具类 xff0c 采用递归方式 xff0c 实现删除非空
  • 在Jetson Nano上实现单目相机 apritag_ros识别

    一 xff0c apritag ros安装 最开始采用克隆源码编译的方式进行安装 xff0c 后来在Jetson nano上有opencv4与opencv3的依赖问题 xff0c 后来索性直接采用二进制安装 xff1a sudo apt g
  • rosserial arduino的安装及使用(ROS控制arduino,arduino创建ROS结点)

    一 xff0c 简介 这个教程展示如何安装arduino IDE和使用rosserial Arduino和Arduino IDE是进行硬件开发的非常好的辅助工具 rosserial arduino包可让ROS和ArduinoIDE一起工作
  • ROS多机通讯踩坑,(主机和从机之间可以订阅话题,但是看不到话题消息)

    在进行ROS分布式通讯的时候 xff0c 已经设置好HOST 而且指定master地址 在树莓派上能够使用rostopic list 查看话题列表 xff0c 但是 xff0c 监听话题时rostopic echo chatter没有内容
  • 基于Microhard P900无人机PIX飞控远距离数传解决方案

    基于Microhard P900无人机PIX飞控远距离数传解决方案 参考文章 xff1a xff08 1 xff09 基于Microhard P900无人机PIX飞控远距离数传解决方案 xff08 2 xff09 https www cnb
  • 串口服务器的作用和工作原理是什么

    要了解串口服务器的作用以及工作原理 xff0c 首先我们就要知道什么是串口服务器 xff0c 简单来说串口服务器就是一种网络通讯接口转换设备 xff0c 它可以将我们一些常见的RS232 RS485 RS422串口转换成TCP IP网络接口
  • C++ 程序编译过程

    C 43 43 程序编译过程 面试高频指数 xff1a 编译过程分为四个过程 xff1a 编译 xff08 编译预处理 编译 优化 xff09 xff0c 汇编 xff0c 链接 编译预处理 xff1a 处理以 开头的指令 xff1b 编译
  • 当源文件与头文件不在同一个目录下的Makefile的编写

    Makefile的作用 xff1a 告诉make命令怎样去编译和链接程序 1 程序的编译与链接 xff1a 编译 xff1a 就是把源文件编译成中间代码 xff0c 为 obj文件 链接 xff1a 把多个 obj文件链接在一块然后执行 主
  • Intel Realsense D435i相关资料

    本文转载自 https www chiphell com thread 1945054 1 1 html xff0c 文末有相关资料可下载查看 https www chiphell com thread 1945054 1 1 html 拿
  • 数据库防火墙&数据库加密与脱敏&数据泄露防护

    写在最前 xff1a 安全产品系列目录 xff1a 目录 amp 总述 数据库防火墙 解决数据库应用侧和运维侧两方面的问题 xff0c 是一款基于数据库协议分析与控制技术的数据库安全防护系统 主动防御 xff0c 实现数据库的访问行为控制
  • Qt里面的函数操作逻辑总结笔记

    Qt里面的函数操作逻辑总结 笔记笔记随时更改 1 xff0c 头文件 h 2 xff0c 源文件 cpp FB 61 函数 xff0c codesys和其他叫法有多不同 qt是c 43 43 的跨平台ui界面编程软件 xff0c 所以他的源
  • Java 接口的三种类型方法

    接口中的方法分别有以下三种 xff1a 1 普通方法 xff1a 使用default修饰的接口方法 xff0c 可以拥有方法体 xff0c 实现类不需要重写 xff0c 可以被实现类继承 xff0c 该特性是Java8以后被提出 xff1b
  • 使用一个for循环创建一个数组(Qt)

    一个for循环创建一个数组的方法 xff1a 主要是一个 取余和 除以的运用 span class token keyword for span span class token punctuation span span class to
  • vs2019提示系统资源不足

    刚换的新电脑 xff0c 8g内存稍微一万就占用80 以上 xff0c 很糟心 尤其在用vs2019的时候 xff0c 就运行一个简单的浮点型和双精度 xff0c 提示系统资源不足 xff0c 吓得我立马打开看看内存占用 xff0c 结果占
  • QT获取系统时间并显示在状态栏

    Qt获取系统时间 span class token comment h span span class token macro property span class token directive keyword include span
  • 2021-01-11

    C 43 43 指针随便笔记 sizeof 先说一个没有成员函数和参数的类 xff0c 占用一个字节 类中的成员函数 xff0c 作为外部指针时 xff0c 需要记得delete xff0c 否则会内存泄漏 指针的sizeof是指针本身的数
  • 关于cmake --build .的理解

    cmake build 该命令的含义是 xff1a 执行当前目录下的构建系统 xff0c 生成构建目标 cmake项目构建过程简述 1 首先 xff0c 使用命令行 cmake lt source tree gt 比如 xff1a cmak
  • Ubuntu20.04下 C/C++ TCP Socket传输文件或图片实例

    server span class token macro property span class token directive hash span span class token directive keyword include s
  • C++通过HTTP请求Get或Post方式请求Json数据

    转载 xff1a C 43 43 通过HTTP请求Get或Post方式请求Json数据 最近在工作中 xff0c 由于合作商只提供uRL xff0c 我这边需要通过HTTP请求Get或Post方式请求Json数据 xff0c 然后解析JSO