c++ http请求,json解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lt623265189/article/details/78413226

一、文章内容

解决c++http请求以及对返回结果json串进行解析,使用jsoncpp库

二、安装jsoncpp插件

vs2015通过NuGet直接安装jsoncpp到项目下





安装好之后,会在项目下有个package包,这个包下面就是jsoncpp库。

三、可以上代码了

http请求

WininetHttp.h文件

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

WininetHttp.cpp文件

/*************************************************
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 <json/json.h>
//#pragma comment(lib, "jsoncpp.lib")
#include <fstream>
#pragma comment(lib, "Wininet.lib")
#include <tchar.h>
using namespace std;

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))
	{
		printf("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;
}

main.cpp文件

#include <iostream>
#include <stdio.h>
#include <string>
#include <map>
#include <thread>
#include "../WininetHttp.h"


int main()
{
	//测试http请求
	CWininetHttp whttp = CWininetHttp();
	string url = "http://tingapi.ting.baidu.com/v1/restserver/ting?format=json&callback=&from=webapp_music&method=baidu.ting.billboard.billList&type=1&size=10&offset=0";
	string json = whttp.RequestJsonInfo(url, Hr_Get, "", "");
	cout << "返回json" << json << endl; return0;}


猜你喜欢

转载自blog.csdn.net/lt623265189/article/details/78413226