2016-06-15 93 views
0

所以情況如下:我能夠成功地從java swing應用程序上傳文件到運行spring web應用程序的我的glassfish 4服務器。緩慢的文件上傳速度httpclient在glassfish上彈出mvc

我的問題是,它需要永遠上傳!我知道有很多因素會在網上加速/減速。我只是想確保我的代碼不是慢點!

對於1.7MB我的測試文件,平均需要約14秒上傳。根據我的ISP和megapath速度測試驗證,我有一個非常一致的50 MB/s連接兩種方式。

似乎有很多不同的方式來實現文件上傳相同的事情。我更像是一個UI開發人員,文件xfer對我來說是新的...我有足夠的時間讓上傳過程工作..我很難從哪裏開始排除故障/優化這個。

我已經包含從客戶端發送文件的代碼以及處理傳入文件的spring控制器中的相關方法。 (請注意,我在JSON形式與文件一起發送關於該文件的元數據)

(客戶端代碼,使用Apache的HTTP客戶端庫)

CloseableHttpClient httpclient = HttpClients.createDefault(); 

long start = System.currentTimeMillis(); 

// request bean to JSON string 
ObjectMapper mapper = new ObjectMapper(); 
String requestBeanAsJSON = mapper.writeValueAsString(requestBeanToSend); 

HttpPost outgoingPostRequest = new HttpPost(serverURL); 

FileBody fileBody = new FileBody(fileToSend, ContentType.DEFAULT_BINARY); 
StringBody stringBody1 = new StringBody("msg", ContentType.MULTIPART_FORM_DATA); 

MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 
builder.addPart("upfile", fileBody); 
builder.addPart("text1", stringBody1); 
HttpEntity entity = builder.build(); 

outgoingPostRequest.setEntity(entity); 

CloseableHttpResponse responseBody = httpclient.execute(outgoingPostRequest); 


long end = System.currentTimeMillis(); 

System.out.println("completed in " + ((end-start)/1000) + " seconds."); 

(服務器代碼,春天,glassfish4)

@RequestMapping(method = RequestMethod.POST, value = "up") 
public @ResponseBody MyReturnObject handleFileUpload(@RequestParam("file") MultipartFile file) 
{ 
    try 
    { 

     BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(FtConstants.getTempUploadBaseDir() + File.separator + uniqueToken + "." + FileUtils.getFileExtension(file.getOriginalFilename())))); 
      FileCopyUtils.copy(file.getInputStream(), stream); 
      stream.close(); 

    } 
    catch(Exception e) 
    { 

    } 

    MyReturnObject returnObject = new MyReturnObject(); 
    returnObject.setToken( RandomStringUtils.randomAlphanumeric(16)); 
    return returnObject; 
} 

有什麼明顯的,我做錯了嗎?就像我上面所說的那樣,它很有用,但它很慢。

在此先感謝您的幫助!

+0

你爲什麼使用'BufferedOutputStream'來複制文件?你不能只做'FileCopyUtils.copy(file.getInputStream(),new FileOutputStream(「theCopiedFile.txt」));''或者乾脆'copy(byte [] in,File out)'方法嗎? – Jaumzera

+0

@Jaumzera - 這幾乎沒有任何區別。 –

+0

@Stephen C根據我在這裏的測試,BufferedOuputStream需要500ms左右的時間(平均值)才能複製214MB文件,而使用非緩衝替代方法需要50ms到同一副本。我認爲10x是相關的。不是嗎?當然,考慮我的硬件規格。 – Jaumzera

回答

1

有什麼明顯的我做錯了嗎?

既然你問......這顯然是錯誤的!它南瓜和所有例外(除了Error及其子類)。

catch(Exception e) 
{ 

} 

請注意,這不會影響傳輸速率,但它可以隱藏各種操作問題......和錯誤。

我看不出會影響傳輸速率的任何問題。我會開始研究使用CPU和網絡性能工具。

+1

stephen c:感謝您的評論...我不得不刪除一些企業特定的代碼,並留下那裏趕上完整性只... – cotfessi

0

有沒有什麼明顯的我做錯了?

以下長相懷疑我:

在客戶端,您通過創建多部分上傳的文件部分:

builder.addPart("upfile", fileBody); 

但控制器正在尋找:

@RequestParam("file") 

而不是

@RequestParam("upfile") 

我懷疑,正如上面已經指出的那樣,您正在吞嚥拋出的異常並返回虛擬隨機響應。你有沒有檢查過這個文件是否真的被上傳了?

+0

謝謝!沒有注意到這種差異,但文件已上傳,然後我可以下載它們並驗證它們的散列,以確保我得到了我所期望的... – cotfessi