c++ http请求,json解析

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 09:08   30   0

一、文章内容

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


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP