首页 > C++通过HTTP请求Get或Post方式请求Json数据(转)

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

原文网址:https://www.cnblogs.com/shike8080/articles/6549339.html

 

#pragma once

#include

#include

#include

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

#include

//#include "common/CVLog.h"

#pragma comment(lib, "Wininet.lib")

#include

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, strHostName:%s, strPageName:%s, port:%d ",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]='';

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;

}

 

转载于:https://www.cnblogs.com/Pond-ZZC/p/9529019.html

更多相关:

  • 经过长期探索,发现一个不需要手动设置线程休眠时间(e.g. std::this_thread::sleep_for(std::chrono::microseconds(1)))的代码: Github: https://github.com/log4cplus/ThreadPool #ifndef THREAD_POOL_H_7e...

  • nth_element(first,nth,last) first,last 第一个和最后一个迭代器,也可以直接用数组的位置。  nth,要定位的第nn 个元素,能对它进行随机访问. 将第n_thn_th 元素放到它该放的位置上,左边元素都小于它,右边元素都大于它. 测试代码: http://www.cplusplus.com...

  • c/c++老版本的rand()存在一定的问题,在转换rand随机数的范围,类型或者分布时,常常会引入非随机性。 定义在 中的随机数库通过一组协作类来解决这类问题:随机数引擎 和 随机数分布类 一个给定的随机数发生器一直会生成相同的随机数序列。一个函数如果定义了局部的随机数发生器,应该将(引擎和分布对象)定义为 st...

  • jsoncpp 是一个C++ 语言实现的json库,非常方便得支持C++得各种数据类型到json 以及 json到各种数据类型的转化。 一个json 类型的数据如下: {"code" : 10.01,"files" : "","msg" : "","uploadid" : "UP000000" } 这种数据类型方便我们人阅读以...

  • 问题如下: 已知一组数(其中有重复元素),求这组数可以组成的所有子集中,子 集中的各个元素和为整数target的子集,结果中无重复的子集。 例如: nums[] = [10, 1, 2, 7, 6, 1, 5], target = 8 结果为: [[1, 7], [1, 2, 5], [2, 6], [1, 1, 6]] 同样之前有...

  • importjava.security.SecureRandom;importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESKeySpec;//结果与DES算...

  • 题目:替换空格 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 输入:s = "We are happy." 输出:"We%20are%20happy." 限制: 0 <= s 的长度 <= 10000 解题: 时间复杂度:O(n) 空间复杂度:O(n) class Solution { public:s...

  • 在C++11标准库中,string.h已经添加了to_string方法,方便从其他类型(如整形)快速转换成字面值。 例如: for (size_t i = 0; i < texArrSize; i++)RTX_Shader.SetInt(string("TexArr[") + to_string(i) + "]", 7 + i);...

  • Ubuntu 14.04安装并升级之后,变成楷体字体非常难看,我昨天搞了一晚上,终于理了个头绪,这里整理一下。 经过网上调研,大家的一致看法是,使用开源字体库文泉驿的微黑字体效果比较理想,甚至效果不输windows平台的雅黑字体。下面我打算微黑来美化Ubuntu 14.04. 1.安装文泉驿微黑字体库 sudo aptitude...

  • 使用string时发现了一些坑。 我们知道stl 容器并不是线程安全的,所以在使用它们的过程中往往需要一些同步机制来保证并发场景下的同步更新。 应该踩的坑还是一个不拉的踩了进去,所以还是记录一下吧。 string作为一个容器,随着我们的append 或者 针对string的+ 操作都会让string内部的数据域动态增加,而动态增加的...

  • 在使用空时,习惯这么赋值  int *p = NULL;  编译器进行解释程序时,NULL会被直接解释成0,所以这里的参数根本就不是大家所想的NULL,参数已经被编译器偷偷换成了0,0是整数。  因此这面的问题就尴尬了 不好意思图片引用于网络中。 为啥呢不是this is the ptr function…这个。这就是C++中的...

  • var d= {a: 1,b: null,c: 3,d: undefined };Object.keys(d).forEach(k=>d[k]==null&&delete d[k]);//去掉值为null或undefined的对象属性//Object.keys(d).forEach(k=>(d[k]==null||d[k]==='')...

  • //ES6获取浏览器url跟参 public getUrlParam = a => (a = location.search.substr(1).match(new RegExp(`(^|&)${a}=([^&]*)(&|$)`)),a?a[2]:null);...

  • 文章目录1. 解决问题2. 应用场景3. 实现如下C++实现C语言实现4. 缺点 1. 解决问题 在简单工厂模式中,我们使用卖衣服进行举例,同一种工厂可以卖很多不同种类的衣服,工厂只是将衣服的生产过程进行了封装。 当我们增加衣服种类的时候,在简单工厂模式中需要修改工厂的代码,破坏了类的开闭原则(对扩展开发, 对修改关闭),...

  • 在服务端数据库的处理当中,涉及中文字符的结构体字段,需要转为Utf8后再存储到表项中。从数据库中取出包含中文字符的字段后,如果需要保存到char *类型的结构体成员中,需要转为Ansi后再保存。从数据库中取出类型数字的字段后,如果需要保存到int型的结构体成员中,需要调用atoi函数进行处理后再保存。 1 static char *...