api.h

#ifndef API_H
#define API_H
typedef void (*ReqCallBack)(QByteArray data);//声明函数指针类型
#define BASE_URI "http://192.168.110.169:6801/hikari-cloud"
#endif // API_H

HttpClient.h

#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H
#include <QMap>
#include <QObject>
#include "utils/api.h"
class HttpClient : public QObject {
Q_OBJECT

public:
static HttpClient& getInstance()
{
static HttpClient instance;
return instance;
}
void reqGet(QString endUrl,QMap<QString,QString> paramMap,ReqCallBack reqCallBack);
void reqPost(QString endUrl,QMap<QString,QString> paramMap,ReqCallBack reqCallBack);
void reqFile(QString endUrl,QString filePath,QMap<QString,QString> paramMap,ReqCallBack reqCallBack);

private:
HttpClient();
HttpClient(const HttpClient&){}
HttpClient& operator==(const HttpClient&){}
};


#endif // HTTPCLIENT_H

HttpClient.cpp

#include "HttpClient.h"
#include "utils/HttpThread.h"

HttpClient::HttpClient(){

}
void HttpClient::reqGet(QString endUrl,QMap<QString,QString> paramMap,ReqCallBack reqCallBack){
HttpThread* httpThread=new HttpThread();
httpThread->mParamMap=paramMap;
httpThread->mEndUrl=endUrl;
httpThread->mReqCallBack=reqCallBack;
httpThread->mReqType=0;
httpThread->start();
}
void HttpClient::reqPost(QString endUrl,QMap<QString,QString> paramMap,ReqCallBack reqCallBack){
HttpThread* httpThread=new HttpThread();
httpThread->mParamMap=paramMap;
httpThread->mEndUrl=endUrl;
httpThread->mReqCallBack=reqCallBack;
httpThread->mReqType=1;
httpThread->start();
}

void HttpClient::reqFile(QString endUrl,QString filePath,QMap<QString,QString> paramMap,ReqCallBack reqCallBack){
HttpThread* httpThread=new HttpThread();
httpThread->mParamMap=paramMap;
httpThread->mEndUrl=endUrl;
httpThread->mReqCallBack=reqCallBack;
httpThread->mReqType=2;
httpThread->mFilePath=filePath;
httpThread->start();
}

HttpThread.h

#ifndef HTTPTHREAD_H
#define HTTPTHREAD_H
#include <QMap>
#include <QThread>
#include "utils/api.h"

class HttpThread : public QThread{
Q_OBJECT

public:
QMap<QString,QString> mParamMap;
QString mEndUrl;
int mReqType=0;//0:get 1:post 2:文件传输
QString mFilePath;

ReqCallBack mReqCallBack;


private:
void run();
void get();
void post();
void filePost();

};
#endif // HTTPTHREAD_H

HttpThread.cpp

#include "HttpThread.h"
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
#include "utils/api.h"
#include <QEventLoop>
#include <QFuture>
#include <QtConcurrentRun>
#include <QMap>
#include <QHttpMultiPart>
#include <QFile>

void HttpThread::get(){
qDebug()<<"HttpThread : "<<QThread::currentThread();
QNetworkAccessManager* netAccessManager= new QNetworkAccessManager;
QString reqUrlStr=BASE_URI+this->mEndUrl;
QUrl reqUrl =reqUrlStr;
QMap<QString, QString>::const_iterator iterator;
for( iterator=mParamMap.constBegin(); iterator!=mParamMap.constEnd(); ++iterator){
qDebug() << iterator.key() <<" " <<iterator.value();
reqUrl.addQueryItem( iterator.key(),iterator.value());
}
qDebug()<<"url:"<<reqUrl;
QNetworkRequest request;
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
request.setUrl(reqUrl);
QNetworkReply *reply = netAccessManager->get(request);
/* 等待请求返回结果 */
QEventLoop loop;
connect(netAccessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));//finish为manager自带的信号,replyFinished是自定义的
loop.exec();
if (reply->error() == QNetworkReply::NoError){
QByteArray recData = reply->readAll();
this->mReqCallBack(recData);
qDebug()<<"req success:" << recData;
}else {
qDebug()<<"req error";
}

/* 释放 reply 内存, 否则会造成内存泄漏 */
reply->deleteLater();
reply=NULL;

}



void HttpThread::post(){
qDebug()<<"HttpThread : "<<QThread::currentThread();
QNetworkAccessManager* netAccessManager= new QNetworkAccessManager;
QString reqUrlStr=BASE_URI+this->mEndUrl;
QUrl reqUrl =reqUrlStr;
QByteArray postData;
postData.append("token=xxx");
QMap<QString, QString>::const_iterator iterator;
for( iterator=mParamMap.constBegin(); iterator!=mParamMap.constEnd(); ++iterator){
qDebug() << iterator.key() <<" " <<iterator.value();
postData.append("&" +iterator.key()+"="+iterator.value());
}
QNetworkRequest request;
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
request.setUrl(reqUrl);
QNetworkReply *reply = netAccessManager->post(request,postData);
/* 等待请求返回结果 */
QEventLoop loop;
connect(netAccessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));//finish为manager自带的信号,replyFinished是自定义的
loop.exec();
if (reply->error() == QNetworkReply::NoError){
QByteArray recData = reply->readAll();
this->mReqCallBack(recData);
qDebug()<<"req success:" << recData;
}else {
qDebug()<<"req error";
}

/* 释放 reply 内存, 否则会造成内存泄漏 */
reply->deleteLater();
reply=NULL;

}




void HttpThread::filePost(){
qDebug()<<"HttpThread : "<<QThread::currentThread();
QNetworkAccessManager* netAccessManager= new QNetworkAccessManager;
QString reqUrlStr=BASE_URI+this->mEndUrl;
QUrl reqUrl =reqUrlStr;
QMap<QString, QString>::const_iterator iterator;
for( iterator=mParamMap.constBegin(); iterator!=mParamMap.constEnd(); ++iterator){
qDebug() << iterator.key() <<" " <<iterator.value();
reqUrl.addQueryItem( iterator.key(),iterator.value());
}
qDebug()<<"url:"<<reqUrl;
QNetworkRequest request;
request.setUrl(reqUrl);
QHttpMultiPart *paramPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
QFile *file = new QFile(mFilePath);
file->open(QIODevice::ReadOnly);
qDebug()<<"===file size===:"<<file->size()<<file->fileName();
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name='file'; filename="+file->fileName()));
filePart.setBodyDevice(file);
file->setParent(paramPart);
paramPart->append(filePart);
QNetworkReply *reply = netAccessManager->post(request,paramPart);
/* 等待请求返回结果 */
QEventLoop loop;
connect(netAccessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));//finish为manager自带的信号,replyFinished是自定义的
loop.exec();
if (reply->error() == QNetworkReply::NoError){
QByteArray recData = reply->readAll();
this->mReqCallBack(recData);
qDebug()<<"req success:" << recData;
}else {
qDebug()<<"req error";
}

/* 释放 reply 内存, 否则会造成内存泄漏 */
reply->deleteLater();
reply=NULL;

}


void HttpThread::run(){
if(this->mReqType==0){
this->get();
}else if(this->mReqType==1){
this->post();
}else if(this->mReqType==2){
this->filePost();
}
}

调用

HttpClient::getInstance().reqGet("/test/fun1",map,[=](QByteArray recData) mutable{
// qDebug("====回调成功的数据======");
qDebug()<<"call back data========:" << recData;
});