我这里客户端是选的qt做的,服务端是选的POCO c++做的服务端.POCO c++服务端地址.
一、异步获取普通josn数据
我这里采用异步接收json数据,因为我在服务器上会回复一个当前路径,所以我会根据这个判断是什么路径的回复执行对应的数据处理
void HTTPManager::sltGetAllPatentInfos()
{
QUrl url(QString("http://%1:9980/DownloadDatabaseData").arg(ServerIp));
QNetworkRequest request(url);
// 发送HTTP GET请求
mNetworkManager->get(request);
}
// 获取 JSON 对象
QJsonObject jsonObj = jsonDoc.object();
QString strMethod=jsonObj["method"].toString();
if(0!=jsonObj["errcode"].toInt())
{
qDebug()<<strMethod<<" faile, errmsg: "<<jsonObj["errmsg"].toString();
return ;
}
if("DownloadDatabaseData"==strMethod)
{
QJsonArray jsonArray=jsonObj["PatentInfos"].toArray();
if(jsonObj["PatentInfos"].isArray())
{
QVector<PatentInfo> vector;
for (int var = 0; var < jsonArray.count(); ++var)
{
QJsonObject jsonObjPatentInfo=jsonArray[var].toObject();
PatentInfo stu;
stu.strCertificateNumber =jsonObjPatentInfo["CertificateNumber"].toString().toStdString();
stu.strRightsOwner =jsonObjPatentInfo["RightsOwner"].toString().toStdString();
stu.strPatentName =jsonObjPatentInfo["PatentName"].toString().toStdString();
stu.strNote =jsonObjPatentInfo["Note"].toString().toStdString();
stu.strFilePath
vector.push_back(stu);
}
emit sigSendPatentInfos(vector);
}
else
{
emit sigClearPatentInfos();
}
}
二、同步获取普通josn数据
同步获取时需要用时间循环去阻塞直到服务器有回复,这种方法还是不太合适,当然看个人喜欢。
QNetworkRequest request;
request.setUrl(QUrl(QString("http://%1:9980/checkPatentByCertificateNumber").arg(ServerIp).toUtf8()));
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
//构造查询
QJsonDocument document;
QJsonObject obj;
obj.insert("CertificateNumberID", QString::fromStdString(strCertificateNumber));
document.setObject(obj);
QByteArray _postData = document.toJson(QJsonDocument::Compact);//以Json字符串的方式传参
QNetworkReply* reply = mNetworkManager->post(request,_postData);
// 等待直到请求完成
QEventLoop loop;
// 连接信号,完成时退出事件循环
QObject::connect(reply, &QNetworkReply::finished, [&]() {
loop.quit();
});
// 进入事件循环,等待请求完成
loop.exec();
// 获取响应的状态码和数据
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug()<<statusCode;
QString strRespose=reply->readAll();
qDebug()<<strRespose;
// 解析 JSON 字符串
QJsonDocument jsonDoc = QJsonDocument::fromJson(strRespose.toUtf8());
// 检查 JSON 是否有效
if (jsonDoc.isNull()) {
qDebug() << "Failed to create JSON doc.";
return -1;
}
// 获取 JSON 对象
QJsonObject jsonObj = jsonDoc.object();
if(0!=jsonObj["errcode"].toInt())
{
return 1;
}
if(jsonObj["repeat"].toBool())
{
return 1;
}
return 0;
三、上传文件到poco服务端
strFilePath为文件完整路径,strPath为我想在服务端保存的路径,strFileName为在服务端文件名。服务器上可以通过下面的方法拿到strPath和strFileName这两个键值
std::string disp;
NameValueCollection params;
MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
_path = params.get("path", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
void HTTPManager::sltAddFile(QString strFilePath,QString strPath,QString strFileName)
{
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType,this);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; path=\""+strPath+"\";filename=\""+ strFileName + "\"")); // file为后端定义的key,filename即为excel文件名
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/xlsx"));
QFile *file = new QFile(strFilePath);
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(imagePart);
QUrl url(QString("http://%1:9980/UploadFile").arg(ServerIp));
QNetworkRequest netReq;
netReq.setUrl(url);
mNetworkManager->post(netReq,multiPart);
}
四、从poco服务端下载文件到本地
get post请求对于服务端来说影响不大,我这里直接用get请求简单点。
这里处理的话,由于文件内容是不定长的,所以我把路径放在头了里面,在下面解析头来传送键值。服务端添加自定头如下
response.setStatus(Poco::Net::HTTPResponse::HTTP_OK);
response.setContentType("application/octet-stream");
response.setContentLength(static_cast<int>(fileStream.size())); // 设置文件大小
response.add("File-Path", strURL); // 添加自定义路径头部
void HTTPManager::sltGetFile(QString strFilePath)
{
QUrl url(QString("http://%1:9980/DownloadFile?Path=%2").arg(ServerIp).arg(strFilePath).toUtf8());
QNetworkRequest request(url);
// 发送HTTP GET请求
mNetworkManager->get(request);
}
QByteArray byty=reply->readAll();
QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
if("application/octet-stream"==contentType)
{
QString strURl=reply->rawHeader("File-Path");
// 保存下载的文件数据
QString strFilePath=QCoreApplication::applicationDirPath()+"/"+QUrl::fromPercentEncoding(strURl.toUtf8());
if(!createPathIfNotExist(strFilePath))
{
qDebug()<<"create file path failed"<<strFilePath;
return;
}
qDebug()<<"strFilePath"<<strFilePath;
QFile file(strFilePath);
if(file.open(QIODevice::WriteOnly))
{
file.write(byty);
file.close();
qDebug() << "File downloaded successfully";
}
qDebug() << "File downloaded failed";
return;
}