一、QNetworkAccessManager、QNetworkRequest、QNetworkReply类介绍
QNetworkAccessManager:是Qt网络模块中的一个类,它用于管理网络请求和响应。可以发送HTTP请求,处理HTTP响应。可以使用不同类型的请求:get,post,put等。
QNetworkRequest:用于设置url,发送请求。
QNetworkReply:用于接受响应。
每当挂起的网络应答完成时,就会发出QNetworkAccessManager::finished()信号。可在此信号对应的槽函数中处理接收到的响应数据,参数将包含一个指向刚刚完成的回复的reply指针。此信号与QNetworkReply::finished()信号同时发出。
注意:不要删除连接到此信号的插槽中的应答对象,要使用deleteLater()。
二、http请求流程
使用QNetworkAccessManager发送HTTP请求的基本流程如下:
创建QNetworkAccessManager对象
创建QNetworkRequest对象,设置请求URL和请求头
使用QNetworkAccessManager的get()、post()、put()等函数发送请求
处理QNetworkReply对象以获取响应数据
三 、使用案例(使用QEventLoop阻塞)
HttpRequest.cpp
HttpResquest::HttpResquest(QObject *parent) : QObject(parent)
{
m_pNetManager = new QNetworkAccessManager(this);
}
void HttpResquest::setUrl(const QString &strUrl)
{
m_pNetRequest.setUrl(QUrl(strUrl));
}
void HttpResquest::setHeader(const QNetworkRequest::KnownHeaders &knownHeader, const QVariant &value)
{
m_pNetRequest.setHeader(knownHeader,value);
}
void HttpResquest::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
{
m_pNetRequest.setRawHeader(headerName,headerValue);
}
bool HttpResquest::post(const QByteArray &byteArray)
{
m_pNetReply = m_pNetManager->post(m_pNetRequest,byteArray);
connect(m_pNetManager,&QNetworkAccessManager::finished,this,&HttpResquest::slotReceiveJsonObj);
QTimer timer;
timer.setSingleShot(true);
QEventLoop eventLoop;
connect(m_pNetReply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
connect(m_pNetReply, &QNetworkReply::finished, m_pNetReply, &QNetworkReply::deleteLater);
connect(&timer,SIGNAL(timeout()),&eventLoop,SLOT(quit()));
timer.start(10000);
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
disconnect(m_pNetManager,&QNetworkAccessManager::finished,this,&HttpResquest::slotReceiveJsonObj);
disconnect(m_pNetReply,&QNetworkReply::finished,&eventLoop,&QEventLoop::quit);
disconnect(m_pNetReply, &QNetworkReply::finished, m_pNetReply, &QNetworkReply::deleteLater);
disconnect(&timer,&QTimer::timeout,&eventLoop,&QEventLoop::quit);
if (timer.isActive())
{
timer.stop();
return true;
}
else
{
m_pNetReply->abort();
qDebug()<<"请求超时";
return false;
}
}
bool HttpResquest::get()
{
m_pNetReply = m_pNetManager->get(m_pNetRequest);
connect(m_pNetManager,&QNetworkAccessManager::finished,this,&HttpResquest::slotReceiveJsonObj);
QTimer timer;
timer.setSingleShot(true);
QEventLoop eventLoop;
connect(m_pNetReply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
connect(m_pNetReply, &QNetworkReply::finished, m_pNetReply, &QNetworkReply::deleteLater);
connect(&timer,SIGNAL(timeout()),&eventLoop,SLOT(quit()));
timer.start(20000);
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
disconnect(m_pNetManager,&QNetworkAccessManager::finished,this,&HttpResquest::slotReceiveJsonObj);
disconnect(&timer,&QTimer::timeout,&eventLoop,&QEventLoop::quit);
if (timer.isActive())
{
timer.stop();
return true;
}
else
{
m_pNetReply->abort();
qDebug()<<"请求超时";
return false;
}
}
void HttpResquest::slotReceiveJsonObj()
{
if(m_pNetReply->error() != QNetworkReply::NoError)
{
qDebug()<<"请求失败!"<<m_pNetReply->error();
emit signalReceiveJsonObj(false,QJsonObject());
return;
}
//检查状态码
//int statusCode = m_pNetReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// 获取返回内容
QByteArray res = m_pNetReply->readAll();
//qDebug()<< QString::fromStdString(res.toStdString());
QJsonDocument document = QJsonDocument::fromJson(res);
if(document.isObject())
{
QJsonObject jsonObj = document.object();
emit signalReceiveJsonObj(true,jsonObj);
return;
}
emit signalReceiveJsonObj(false,QJsonObject());
}
post请求:
HttpResquest *httpResquest = new HttpResquest(this);
httpResquest->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
httpResquest->setUrl("http://ip:port/api/test1");
QJsonObject dataObj;
dataObj.insert("time",QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
dataObj.insert("name","张三");
dataObj.insert("age",25);
QJsonDocument doc(dataObj);
connect(httpResquest,&HttpResquest::signalReceiveJsonObj,this,[=](const bool &result,const QJsonObject &jsonObj){
if(!result)
{
qDebug()<<"--请求失败";
return;
}
//根据定义的接口
int code = jsonObj.value("code").toInt();
if(code != 0)
{
qDebug()<<"失败";
return;
}
qDebug()<<"成功";
});
bool flag = httpResquest->post(doc.toJson());
if(!flag)
{
qDebug()<<"--请求超时!";
}
delete httpResquest;
httpResquest = NULL;
get请求:
HttpResquest *httpResquest = new HttpResquest(this);
QString url = "http://ip:port/api/test3";
url += "?";
url += QString("name=%1").arg(ui->lineEdit->text());
url += QString("&pwd=%1").arg(ui->lineEdit_2->text());
httpResquest->setUrl(url);
httpResquest->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
connect(httpResquest,&HttpResquest::signalReceiveJsonObj,this,[=](const bool &result,const QJsonObject &jsonObj){
if(!result)
{
qDebug()<<"--请求失败";
return;
}
int code = jsonObj.value("code").toInt();
if(code != 0)
{
qDebug()<<"失败";
return;
}
qDebug()<<"成功";
});
bool flag = httpResquest->get();
if(!flag)
{
qDebug()<<"--请求超时!";
}
delete httpResquest;
httpResquest = NULL;