0
点赞
收藏
分享

微信扫一扫

C++如何使用libcurl发送post请求的三种content-type的封装


作者:虚坏叔叔

早餐店不会开到晚上,想吃的人早就来了!😄

C++如何使用libcurl发送post请求的三种content-type的封装

C++如何使用libcurl发送post请求的3中content-type的封装。

我们知道​​http​​​协议的post请求的​​content-type​​​有三种方式,其他语言都能很方便的设置,那么​​c++​​​如何实现​​post​​​请求不同​​content-type​​的请求能,下面封装好了大家需要可以直接拿


一、以下是封装好的http请求类(get/post)

下面封装了http请求工具类,在外部直接调用此类即可

HttpLink.h

//********************************************************************
//
// @copyright www.xuhss.com
// @version v1.0
// @file www.xuhss.com
// @author w
// @date 202/1/21 15:01
// @brief 连接服务端
//*********************************************************************

#pragma once

#include "..\..\..\ThridLibrary\curl-7.62.0\include\curl\curl.h"
#pragma comment(lib,"libcurl.lib")

class CHttpLink
{
public:
CHttpLink();
~CHttpLink();

/**
* @brief 使用Post 用http连接服务端
*
* @param const std::string &url 网址
* @param const std::string &postParams param参数
* @param int nPort 端口
* @param std::string &strResponse 返回值
* @param std::list<std::string> listRequestHeader 请求头
* @param bool bResponseIsWithHeaderData 是否带请求头
* @param int nConnectTimeout
* @param int nTimeout
* @return CURLcode
*/
CURLcode CurlPostRequst(const std::string &url, const std::string &strParams, int nPort,
std::string &strResponse, std::list<std::string> listRequestHeader,
bool bResponseIsWithHeaderData = false, int nConnectTimeout = 10, int nTimeout = 10);

/**
* @brief 使用Post 用http连接服务端
*
* @param const std::string &url 网址
* @param std::string &strResponse 返回值
* @param int nPort 端口
* @param std::list<std::string> listRequestHeader 请求头
* @param bool bResponseIsWithHeaderData 是否带请求头
* @param int nConnectTimeout
* @param int nTimeout
* @return CURLcode
*/
CURLcode CurlGetRequst(const std::string &url, std::string &strResponse,
int nPort, std::list<std::string> listRequestHeader,
bool bResponseIsWithHeaderData = false, int nConnectTimeout = 10, int nTimeout = 10);
};

HttpLink.cpp

#include "StdAfx.h"
#include "HttpLink.h"


CHttpLink::CHttpLink()
{
}


CHttpLink::~CHttpLink()
{
}

size_t WriteData(void *buffer, size_t size, size_t nmemb, void *userp)
{
std::string* str = dynamic_cast<std::string*>((std::string *)userp);
if (NULL == str || NULL == buffer)
{
return -1;
}

char* pData = (char*)buffer;
str->append(pData, size * nmemb);
return nmemb;
}

CURLcode CHttpLink::CurlPostRequst(const std::string &url, const std::string &strParams, int nPort,
std::string &strResponse, std::list<std::string> listRequestHeader,
bool bResponseIsWithHeaderData/* = false*/, int nConnectTimeout/* = 10*/, int nTimeout/* = 10*/)
{
// 初始化
CURL *curl = curl_easy_init();
struct curl_httppost* post = NULL;
struct curl_httppost* last = NULL;

// 返回值
CURLcode res;
if (curl)
{
// set params
// 1为Post,0为Get方式
curl_easy_setopt(curl, CURLOPT_POST, 1);

// 设置网址
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // url

// 设置端口
curl_easy_setopt(curl, CURLOPT_PORT, nPort); //port

//构建HTTP报文头
struct curl_slist* headers = NULL;
if (listRequestHeader.size() > 0)
{
std::list<std::string>::iterator iter, iterEnd;
iter = listRequestHeader.begin();
iterEnd = listRequestHeader.end();
for (iter; iter != iterEnd; iter++)
{
headers = curl_slist_append(headers, iter->c_str());
}
if (headers != NULL)
{
//设置http请求头信息
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
}
}
else
{
headers = curl_slist_append(headers, "Content-Type:application/x-www-form-urlencoded");
if (headers != NULL)
{
//设置http请求头信息
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
}
}

// 设置param参数
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strParams.c_str());

// 构造post参数 (表单的形式)
// curl_formadd(&post, &last, CURLFORM_PTRNAME, "materialistid{}", CURLFORM_PTRCONTENTS, strParams, CURLFORM_END);
// curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //返回的头部中有Location(一般直接请求的url没找到),则继续请求Location对应的数据
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);

// 回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData);

// 获取返回数据
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

//响应体中是否包含了头信息
if (bResponseIsWithHeaderData)
{
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
}
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nConnectTimeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeout);

// 开始连接
res = curl_easy_perform(curl);
if (headers != NULL)
{
curl_slist_free_all(headers); //free the list again
}
}

//清理
curl_easy_cleanup(curl);
return res;
}

CURLcode CHttpLink::CurlGetRequst(const std::string &url, std::string &strResponse,
int nPort, std::list<std::string> listRequestHeader,
bool bResponseIsWithHeaderData/* = false*/, int nConnectTimeout/* = 10*/, int nTimeout/* = 10*/)
{
// init curl
CURL *curl = curl_easy_init();
// res code
CURLcode res;
if (curl)
{
// set params
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // url
curl_easy_setopt(curl, CURLOPT_PORT, 18080); //port
curl_easy_setopt(curl, CURLOPT_POST, 0); // get reqest
//构建HTTP报文头
struct curl_slist* headers = NULL;
if (listRequestHeader.size() > 0)
{
std::list<std::string>::iterator iter, iterEnd;
iter = listRequestHeader.begin();
iterEnd = listRequestHeader.end();
for (iter; iter != iterEnd; iter++)
{
headers = curl_slist_append(headers, iter->c_str());
}
//headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
//headers = curl_slist_append(headers, "Content-Type:application/x-www-form-urlencoded");
if (headers != NULL)
{
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);//设置http请求头信息
}
}
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); // if want to use https
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); // set peer and host verify false
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
if (bResponseIsWithHeaderData)
{
curl_easy_setopt(curl, CURLOPT_HEADER, 1);//响应体中是否包含了头信息,比如Content-Type:application/json;charset=UTF-8
}
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nConnectTimeout); // set transport and time out time
curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeout);
// start request
res = curl_easy_perform(curl);
if (headers != NULL)
{
curl_slist_free_all(headers); //free the list again
}
}
// release curl
curl_easy_cleanup(curl);
return res;
}

二、调用HttpLink post的三种content-type

2.1 Content-Type:application/x-www-form-urlencoded

::string strUser, strPass;
strUser = CT2A(strUserName.GetBuffer());
strPass = CT2A(strPossWord.GetBuffer());
strUserName.ReleaseBuffer();
strPossWord.ReleaseBuffer();
std::string strLoginParam = "username=";
strLoginParam += strUser;
strLoginParam += "&password=";
strLoginParam += strPass;

std::string strResponse;
std::list<std::string> listRequestHeader;
listRequestHeader.push_back("Content-Type:application/x-www-form-urlencoded");

CHttpLink httpLink;
httpLink.CurlPostRequst(_strURL, strLoginParam, _nPort, strResponse, listRequestHeader, true);

// 从返回值中截取token值
std::string strError = GetTokenFromStr(strResponse, _strToken);
if (!strError.empty())
{
CString strWError = strError.c_str();
MessageBox(strWError, _T("提示"), MB_OK | MB_ICONINFORMATION);
return;
}
else
{

}

2.2 Content-Type:application/json;charset=UTF-8

// 构建json数据作为param传递
cJSON *pJson = cJSON_CreateObject();

//创建一个整型数组
cJSON *pIntArr = cJSON_CreateArray();

cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
int nCount = (int)nArr.size();
for (int i = 0; a && i<nCount; i++)
{
n = cJSON_CreateDouble((long double)((unsigned int)nArr[i]), 1);
//n = cJSON_CreateNumber(nArr[i]);
if (!i)
a->child = n;
else
{
p->next = n;
n->prev = p;
}
p = n;
}

cJSON_AddItemToObject(pJson, "materialistid", a);
char *json_data = cJSON_Print(pJson);

// 构建网址
std::string strRespose;
std::string strUrl = BuildUrl(_strIP, _strPort, _strPrefix, _strController);

std::list<std::string> listRequestHeader;
listRequestHeader.push_back("Content-Type:application/json;charset=UTF-8");
listRequestHeader.push_back(strToken);
listRequestHeader.push_back("endPointType:ROLE_DEVELOP");

CHttpLink httpLink;
httpLink.CurlPostRequst(strUrl, json_data, _nPort, strRespose, listRequestHeader, true);

// 截取Json数据
CStringA strJsonData = InterceptJsonDataFromStr(strRespose);
const char* result = new char[2 * strJsonData.GetLength() + 1];
cJSON* cjson = cJSON_Parse(strJsonData, &result);
delete[] result;
if (cjson == NULL || cjson->type == cJSON_NULL)
return;

// 获取结果
cJSON* pResultArr = cJSON_GetObjectItem(cjson, "result");
if (NULL == pResultArr || pResultArr->type == cJSON_NULL)
return;

int nSize = cJSON_GetArraySize(pResultArr);
cJSON* pSubItem = pResultArr->child;
for (int i = 0; i < nSize; ++i)
{
cJSON* pSubChildItem = pSubItem->child;
int nLength = cJSON_GetArraySize(pSubItem);
MatDataValue dataValue;
for (int j = 0; j < nLength; ++j)
{
CVariantData variantData = BuildVariantData(pSubChildItem);

CString strKey = UTF8StdstringToCString(pSubChildItem->string);
dataValue.keyValueMap[strKey] = variantData;
pSubChildItem = pSubChildItem->next;
}

_matDataValueArr.push_back(dataValue);
pSubItem = pSubItem->next;
}

cJSON_Delete(cjson);

2.3 Content-Type: multipart/form-data

void CDlgStandardResultApply::UploadFile(std::string& strUrl, std::string& strFilePath, std::string& strResult)
{
std::string stdXmCode = CW2A(_strXmCode.GetString());
std::string stdPrjCode = CW2A(_strPrjCode.GetString());

std::string strError;
CString strResponseValue;

CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: multipart/form-data");
headers = curl_slist_append(headers, "endPointType: web");
headers = curl_slist_append(headers, _strToken.c_str());
headers = curl_slist_append(headers, "Cookie: JSESSIONID=82E632D537D25075EDD98E6BE1ADF0F7");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_mime *mime;
curl_mimepart *part;
mime = curl_mime_init(curl);
part = curl_mime_addpart(mime);
curl_mime_name(part, "file");
curl_mime_filedata(part, strFilePath.c_str());
part = curl_mime_addpart(mime);
curl_mime_name(part, "resultid");
curl_mime_data(part, strResult.c_str(), CURL_ZERO_TERMINATED);
part = curl_mime_addpart(mime);
curl_mime_name(part, "projectCode");
curl_mime_data(part, stdXmCode.c_str(), CURL_ZERO_TERMINATED);
part = curl_mime_addpart(mime);
curl_mime_name(part, "itemProjectCode");
curl_mime_data(part, stdPrjCode.c_str(), CURL_ZERO_TERMINATED);
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);

std::string stdResponse; // post返回后的数据
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); //绑定相应
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stdResponse);

res = curl_easy_perform(curl);
curl_mime_free(mime);

strResponseValue = CA2W(stdResponse.c_str(), CP_UTF8);
}
curl_easy_cleanup(curl);

if (res != CURLE_OK)
{
strError = curl_easy_strerror(res);
return;
}

CString strKey = L"code";
std::string stdKey = CW2A(strKey);
std::string stdResValue = CW2A(strResponseValue);
std::string stdResultCode;

strError = GetJsonResultFromStr(stdResValue, stdResultCode, stdKey);
if (!strError.empty())
{
CString strWError = strError.c_str();
MessageBox(strWError, _T("提示"), MB_OK | MB_ICONINFORMATION);
return;
}

CString strResuult = CA2W(stdResultCode.c_str(), CP_UTF8);
if (L"0" != strResuult)
return;

CString strErrorInfo = L"上传成功!";
MessageBox(strErrorInfo, _T("提示"), MB_OK | MB_ICONINFORMATION);
}

三、总结

  • 本文主要介绍C++如何使用libcurl发送post请求的3中content-type的封装



举报

相关推荐

0 条评论