Qt Http QHttpMultiPart上传文件到java http服务器
1.最近项目用到了Qt上传文件到HTTP服务器,由于之前做过一个http接收文件的服务器,所以直接拿来调试。由于对http的了解一个不够深入,调试了许久都没有成功上传文件到服务器。之前是写的服务器一直是用网页的方式和postman来模仿post文件。
由于找不到失败的原因,所以直接用wareshark来抓包看一下Qt post的数据和网页上传有什么区别。在第4.节图中给出了网页上传文件时wareshark抓取到的数据包。
2.经过调试后可用的Qt 代码,由于我的http是在多线程中使用,所以在此处加入了一个QEventLoop来同步等待返回上传结果。
void HttpObject::uploadFile()
{
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QString path = QString("/home/maowendi/Desktop/image.jpg");
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"image.jpg\""));
imgFile = new QFile(path);
imgFile->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
imgFile->setParent(multiPart);
multiPart->append(imagePart);
QUrl url("http://172.20.149.148:8089/upload-file");
QNetworkRequest request(url);
uploadFileReply = m_httpNAM->post(request, multiPart);
multiPart->setParent(uploadFileReply);
connect(uploadFileReply,SIGNAL(finished()),this,SLOT(httpUploadFinished()));
QEventLoop eventLoop;
connect(m_httpNAM, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
eventLoop.exec();
}
void HttpObject::httpUploadFinished()
{
if(uploadFileReply->error() == QNetworkReply::NoError) {
qDebug()<<"upload file finished";
imgFile->flush();
imgFile->close();
uploadFileReply->deleteLater();
uploadFileReply = NULL;
delete imgFile;
imgFile = NULL;
}
else
{
qDebug()<<"error string:"<<uploadFileReply->errorString();
uploadFileReply->deleteLater();
}
}
3.Qt官方例程的代码如下,根据官方例程还是要做一点修改才能成功上传文件的。
其中红色框部分根据我自己的java服务器测试抓包数据进行了修改。见下图
4.抓包工具Wareshark,抓取数据包如下
5.结果执行代码后服务器返回成功
6.Java服务器处理接收文件代码
/**
* 上传单个文件` 1
*
* @param file 上传文件 MultipartFile 的对象
* @return 上传的结果
*/
@RequestMapping(value = "/upload-file", method = RequestMethod.POST)
@ResponseBody
public String uploadFile(HttpServletRequest request,@RequestParam("file") MultipartFile file) {
saveFile(file);
System.out.println(filePath);
ReturnWeb ret = new ReturnWeb();
ret.setCode(1);
ret.setCount(0);
ret.setMsg("Success");
JSONObject jsonS = (JSONObject) JSON.toJSON(ret);
return jsonS.toString();
}
/**
* 把 HTTP 请求中的文件流保存到本地
*
* @param file MultipartFile 的对象
*/
private boolean saveFile(MultipartFile file) {
if (!file.isEmpty()) {
try {
// getRealPath() 取得 WEB-INF 所在文件夹路径
// 如果参数是 "/temp", 当 temp 存在时返回 temp 的本地路径, 不存在时返回 null/temp (无效路径)
//String path ="D:\\IDEAPro\\File"+ File.separator + file.getOriginalFilename();;
String path =servletContext.getRealPath("") + File.separator + file.getOriginalFilename();
FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(path));
fileName = file.getOriginalFilename();
filePath = "http://172.20.149.148:8089/"+fileName;
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}