简单写了个Http的工具类,实现发送请求,自动记录请求及返回数据,通过信号机制实现异步回调。
头文件:HttpFun.h
#ifndef HTTPFUN_H
#define HTTPFUN_H
#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QTimer>
#include <QString>
#include <QByteArray>
#include <QByteArray>
#include <QSslConfiguration>
#include <QtNetwork/QNetworkRequest>
//http请求类
class HttpFun : public QObject
{
Q_OBJECT
public:
explicit HttpFun(QObject *parent = 0);
void sendRequest(const QString& strUrl,const QByteArray& post_data);//根据url发起http请求
void sendRequest(const QString& key);//按照key发送请求
void sendRequest();//发送请求
void append(QString data);//追加一个数据到data
signals:
void signal_requestFinished(bool bSuccess,const QByteArray& byteResult); //http请求结束
public slots:
void slot_requestFinished(); //http请求结束
void slot_requestTimeout(); //请求超时
private:
void dolog(QString log);
QNetworkAccessManager* m_pNetworkManager;//网络管理类
QNetworkReply* m_pNetworkReply; //封装请求返回信息
QTimer* m_pTimer; //请求超时计时器
QString m_strUrl; //记录当前请求的url
QByteArray postdata;//postdata
};
#endif // HTTPFUN_H
源文件:Httpfun.cpp
#include "HttpFun.h"
#include <QTextCodec>
#include "common.h"
#include "QDir"
HttpFun::HttpFun(QObject *parent) :
QObject(parent)
{
m_pNetworkManager = new QNetworkAccessManager(this);
m_pNetworkReply = NULL;
m_pTimer = new QTimer;
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(slot_requestTimeout()));//超时信号
postdata.append(styleManager->getString("apiversion")+"&");//api版本数据
}
void HttpFun::dolog(QString log){
QDir dir("./logs/");
if(!dir.exists())
{
dir.mkdir(QDir::currentPath()+"/logs/");
}
QFile file("./logs/http"+QDateTime::currentDateTime().toString("yyyyMMdd")+".log");
file.open(QIODevice::Append | QIODevice::WriteOnly );
QTextStream text_stream(&file);
text_stream <<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")<<"\r\n"<< log << "\r\n";
file.flush();
file.close();
}
//发起请求
void HttpFun::sendRequest(const QString &strUrl,const QByteArray& post_data)
{
dolog(strUrl);
QString str;
str.append(post_data);
dolog(post_data);
m_strUrl = strUrl;
QNetworkRequest netRequest;
netRequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
netRequest.setHeader(QNetworkRequest::ContentLengthHeader, post_data.length());
netRequest.setUrl(QUrl(strUrl)); //地址信息
if(strUrl.toLower().startsWith("https"))//https请求,需ssl支持(下载openssl拷贝libeay32.dll和ssleay32.dll文件至Qt bin目录或程序运行目录)
{
QSslConfiguration sslConfig;
sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfig.setProtocol(QSsl::TlsV1_1);
netRequest.setSslConfiguration(sslConfig);
}
// QString strBody; //http body部分,可封装参数信息
// QByteArray contentByteArray = strBody.toLatin1();//转成二进制
m_pNetworkReply = m_pNetworkManager->post(netRequest,post_data);//发起post请求
// m_pNetworkReply = m_pNetworkManager->get(netRequest); //发起get请求
connect(m_pNetworkReply,SIGNAL(finished()),this,SLOT(slot_requestFinished())); //请求完成信号
int timeout=cfg->NetTimeOut;
// qDebug()<<"timeout="<<timeout;
if(timeout<3 || timeout>600){
timeout=30;//默认30秒
}
//qDebug()<<"timeout="<<timeout;
m_pTimer->start(timeout*1000);
}
///
/// \brief 根据key来发送请求
/// \param key
///
void HttpFun::sendRequest(const QString &key){
QString apiurl=styleManager->getString(key);
sendRequest(apiurl,postdata);
qDebug()<<apiurl<<postdata;
}
///
/// \brief 直接发送请求
///
void HttpFun::sendRequest(){
QString apiurl=styleManager->getString("apipath");
sendRequest(apiurl,postdata);
qDebug()<<apiurl<<postdata;
//log(apiurl);
// log(postdata);
}
void HttpFun::append(QString data)
{
postdata.append(data+"&");
}
//请求结束
void HttpFun::slot_requestFinished()
{
m_pTimer->stop();//关闭定时器
QByteArray resultContent = m_pNetworkReply->readAll();
// QTextCodec* pCodec = QTextCodec::codecForName("UTF-8");
// QString strResult = pCodec->toUnicode(resultContent);
QString rst;
rst.append(resultContent);
dolog(rst);
int nHttpCode = m_pNetworkReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();//http返回码
if(nHttpCode == 200)//成功
{
emit signal_requestFinished(true,resultContent);//请求成功
}
else
{
emit signal_requestFinished(false,resultContent);//请求失败
}
//每次结束清空内存 所以不适合用静态实例
m_pNetworkReply->deleteLater();
this->deleteLater(); //释放内存
}
//请求超时
void HttpFun::slot_requestTimeout()
{
emit signal_requestFinished(false,"timeout");//请求失败
m_pNetworkReply->deleteLater();
this->deleteLater();//释放内存
}
调用示例:
HttpFun * http=new HttpFun();
connect(http,SIGNAL(signal_requestFinished(bool,const QByteArray&)), this,SLOT(slot_loginFinished(bool,const QByteArray&)));//http请求结束信号
http->append("请求地址");
http->append("uname="+ui->txtName->text());//参数
http->append("pword="+ui->txtPwd->text());//参数
http->sendRequest();//请求登录
请求结束信号里面写数据处理代码。
//请求结束
void LoginDialog::slot_loginFinished(bool bSuccess, const QByteArray &byteResult)
{
// qDebug()<<"login result " <<byteResult;
if(bSuccess)
{
//byteArray转换成json对象
QJsonObject data = QJsonDocument::fromJson(byteResult).object();
//处理数据
}
}