2013-11-28 58 views
3

我想使用HttpClient 4.3.1上傳文件。我需要添加以形成多部分輸入流(以控制上載進度。)而不是File對象。 這是我的代碼:Java Apache HttpClient錯誤上傳文件

 byte[] dump = ...; 

     HttpClient httpclient = new DefaultHttpClient(); 
     HttpPost httppost = new HttpPost(SENDLOG_URL);  

     MultipartEntityBuilder meb = MultipartEntityBuilder.create(); 
     meb.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 
     // THIS WORKS!! meb.addBinaryBody("log", new File("C:\\temp.zip"), ContentType.APPLICATION_OCTET_STREAM,"log.zip"); 
     InputStream is=new FileInputStream("C:\\temp.zip") 
     meb.addBinaryBody("log", is, ContentType.DEFAULT_BINARY, "log.zip");    
     httppost.setEntity(meb.build()); 
     HttpResponse resp=httpclient.execute(httppost); 
     is.close(); 

使用方法MultipartEntityBuilder.addBinaryBody(〜應變,文件)它的工作原理,但使用MultipartEntityBuilder.addBinaryBody(〜應變,InputStream的)這是行不通的。

Java客戶端不會引發任何錯誤,但是這是遠程服務器(Apache的)的答案:

HTTP/1.1 400錯誤的請求 [日期:星期四,2013年11月28日09:服務器:Apache/2.4.6(Unix)mod_fcgid/2.3.7,Content-Length:226, Connection:close,Content-Type:text/html; charset = iso-8859-1]

爲什麼新的File()和新的FileInputStream()之間存在這種奇怪的行爲?

+0

獲得響應後關閉連接。 fos.close(); –

+0

你的意思是FileOutputStream?你真的可以忽略這一點,它只是寫入臨時文件。 – Tobia

+0

哎呀對不起.....你可以創建一個輸入流的實例,並將其傳遞給addBinaryBody方法,一旦你收到響應關閉連接使用實例 –

回答

2

這一切都很簡單。在前一種情況下,考慮到所有部分的長度是已知的,可以計算多部分實體內容的總長度。這樣的實體可以包含在由Content-Length標題定界的請求中。在後一種情況下,不能確定總的實體長度,並且用塊編碼傳輸請求。顯然,有些協議合規性的服務器端腳本無法處理沒有Content-Length標頭的請求。

+0

我知道內容長度(這個輸入流是一個文件流),可以強制它? – Tobia

+0

我解決了擴展org.apache.http.entity.mime.content.InputStreamBody改變public long getContentLength()方法。謝謝。 – Tobia

+0

除了擴展'InputStreamBody'之外的任何解決方案? – ulab