Qt Http QHttpMultiPart上傳檔案到java http伺服器
阿新 • • 發佈:2018-11-01
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; }