QNetworkRequest request(serviceUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
networkManager->post(request, postData.encodedQuery());//HTTP Post请求部分包头
T assistant 中有关QHttp的说明,建议我们使用 QNetworkAccessManager 和 QNetworkReply 而非QHttp,因为前者的API更多,并且提供了更丰富的错误处理。
下面是利用QNetworkAccessManager 和 QNetworkReply 实现的一个http下载类,由于QNetworkAccessManager里面没有提供网络连接中断和超时的错误处理,所以中间我用了QTimer来进行这个容错处理。
下面代码里,如果发现在下载过程中网络中断,我将重新下载 所有文件 ,并且永不停悉。(maybe it's not used for u, u can comment that).
Head file:
#ifndef IHTTPDOWNLOADS_H #define IHTTPDOWNLOADS_H #include<QObject>#include<QNetworkAccessManager>#include<QUrl>#include<QFile>#include<QNetworkReply>#include<QTimer>#include<QProgressBar>class iHttpDownloadS :public QObject { Q_OBJECT public:explicit iHttpDownloadS(QObject *parent = 0, QProgressBar *_progressBar = 0);~iHttpDownloadS();bool getFileFromURL(const QUrl &url,const QString &filePath);/* get file from url which we need to download, and restore to filePath */const QString &getLastErrorMessage();/* if error occurs, use this to get the error message */void setErrorMessage(const QString &msg);/* set _errMsg */ signals:public slots:void replyFinished(QNetworkReply*);/* download finished */void replayDownloadProgress(qint64, qint64);/* downloading... */void slotError(QNetworkReply::NetworkError);/* handle error */void slotReadyRead();/* ready read */void handleTimeOut();/* handle time out */private: QNetworkAccessManager *_downloadManager; QNetworkReply *_reply; QString _errMsg; QFile _file; QProgressBar *_progressBar; QTimer *_timeOut; QString _filePath; QUrl _url;};#endif// IHTTPDOWNLOADS_H
Implementation file:
#include"ihttpdownloads.h"#include<QDebug>
iHttpDownloadS::iHttpDownloadS(QObject *parent, QProgressBar *bar):
QObject(parent), _progressBar(bar){
_downloadManager =new QNetworkAccessManager(this);
_timeOut =new QTimer(this);connect(_downloadManager,SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));connect(_timeOut,SIGNAL(timeout()),this, SLOT(handleTimeOut()));}
iHttpDownloadS::~iHttpDownloadS(){
_reply->deleteLater();
_downloadManager->deleteLater();}bool iHttpDownloadS::getFileFromURL(const QUrl &url,const QString &filePath)/* get file from url which we need to download, and restore to filePath */{/* confirm the url is valid or not */if(!url.isValid()){
setErrorMessage(QString("Error:URL has specify a invalid name."));returnfalse;}if(url.scheme()!="http"){
setErrorMessage(QString("Error:URL must start with 'http:'"));returnfalse;}if(url.path().isEmpty()){
setErrorMessage(QString("Error:URL's path is empty."));returnfalse;}if(filePath.isEmpty()){
setErrorMessage(QString("Error:invalid filePath."));returnfalse;}
_file.setFileName(filePath);if(!_file.open(QIODevice::WriteOnly)){
setErrorMessage(QString("Error:Cannot open file."));returnfalse;}
_url = url;
_filePath = filePath;
_reply = _downloadManager->get(QNetworkRequest(url));connect(_reply,SIGNAL(readyRead()),this, SLOT(slotReadyRead()));connect(_reply,SIGNAL(downloadProgress(qint64, qint64)),this, SLOT(replayDownloadProgress(qint64, qint64)));connect(_reply,SIGNAL(error(QNetworkReply::NetworkError)),this, SLOT(slotError(QNetworkReply::NetworkError)));returntrue;}const QString &iHttpDownloadS::getLastErrorMessage(){return _errMsg;}void iHttpDownloadS::setErrorMessage(const QString &msg){
qDebug()<<msg;
_errMsg = msg;}/* slots */void iHttpDownloadS::handleTimeOut(){
qDebug()<<"time out..";
_timeOut->stop();if(_file.isOpen()){
_file.close();}
getFileFromURL(_url, _filePath);/* try again */}void iHttpDownloadS::replyFinished(QNetworkReply* reply)/* download finished */{
_file.waitForBytesWritten(10000);/* wait 10s for write to file complete, can comment this */if(0 == _file.size()){
qDebug()<<"Nothing be downloaded.";}else{/* add our updateUI code here... */
qDebug()<<"finished";}}void iHttpDownloadS::replayDownloadProgress(qint64 done, qint64 total)/* downloading... */{
qDebug()<<QString("%1%").arg(done /(double)total * 100);if((0 != _progressBar)&&(0 != total)){
_progressBar->setMaximum(total);
_progressBar->setValue(done);}}void iHttpDownloadS::slotReadyRead()/* if this is not been fired for 30s, we trate this timeout, and the timout handle will re download the file */{
_file.write(this->_reply->readAll());if(_timeOut->isActive()){
_timeOut->stop();}
_timeOut->start(30000);/* wait 30 seconds */}void iHttpDownloadS::slotError(QNetworkReply::NetworkError errorCode)/* handle error */{
qDebug()<<"error:"<<errorCode;
setErrorMessage(QString("Error:NetworkError code:%1").arg(errorCode));if(_file.isOpen()){
_file.close();}
getFileFromURL(_url, _filePath);/* try again */}
QNetworkRequest request(serviceUrl);request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");networkManager->post(request, postData.encodedQuery());//HTTP Post