2017-06-06 24 views
0

HTTPS流我有一個REST服務採用https接受文件上傳的多連接(即元數據文件和文件本身)REST服務 - 多個部分的POST(JSON和文件)上使用澤西

我怎麼能使用Jersey(用於websphere)或HttpClient調用REST服務並將文件作爲多部分發送。我希望將文件發送爲多個不同大小的流,因爲我們可以使文件超過1GB。此外,REST服務正在使用Windows NT身份驗證進行授權,並且位於https上。

任何人都可以舉例說明我如何實現這一目標?我使用了多部分httpClient。以流的形式發送它不起作用。以下是我的代碼使用httpClient 4.5.2

====================================

InputStream stream = new FileInputStream("test.doc"); 

MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); 
entityBuilder.setStrictMode(); 

InputStreamBody streamBody = new InputStreamBody(stream, docHandler.getFilename()); 

FormBodyPart filePart = FormBodyPartBuilder.create() 
       .setName("Binary") 
       .addField(Constants.RETRIEVAL_NAME_FIELD, "test.doc")    
       .addField("Content-Type",docHandler.getContentType()) 
       .setBody(streamBody) 
       .build(); 
entityBuilder.addPart(filePart); 

HttpPost httpPostRequest = new HttpPost(); 
httpPostRequest.setEntity(entityBuilder.build()); 

httpClient.execute(httpPostRequest); 

==================================== 但是,當我執行此代碼時,我收到以下錯誤

org.apache.http.client.NonRepeatableRequestException:爲什麼我收到這個錯誤不能與非重複的請求實體

重試請求的任何想法。如果我將流轉換爲字節數組並使用ByteArrayBody代替,那麼它工作正常,但我注意到在Fiddler中有三個請求調用正在對服務器進行,​​並且在每次調用中都會複製文件的全部內容。所以,如果我的文件是1GB,那麼整個內容將被髮送到服務器三次。

首先,如何實現以大塊或多個流發送大文件,以便在一次調用中不發送整個文件。其次,有沒有辦法避免3次調用服務器進行NTLM身份驗證?

任何指針?

乾杯!

+0

[Jersey 2 Multipart upload client]可能重複(https://stackoverflow.com/questions/24637038/jersey-2-multipart-upload-client) – andih

+0

嗨andih,這個鏈接是使用簡單的http連接,並沒有有認證。在我的情況下,RESTful服務在https上,並使用NTLM身份驗證機制。有沒有什麼好的例子可以通過https使用NTLM認證機制通過REST服務將文件上傳爲流(我是inputstream)?另外,我們有運行客戶端Java應用程序的websphere。服務器在.Net中實現。 – sab123

+0

Apache HTTP客戶端支持http和https。在大多數情況下,你甚至不需要修改你的代碼。 NTLM身份驗證是http(s)的「頂部」。 Apache Http客戶端版本> 4.1(4.2.3)支持[NTLM](https://hc.apache.org/httpcomponents-client-ga/ntlm.html)。看起來你在一個問題中詢問不同的事情。塊上載如何重複。 NTLM認證方案在[這裏]描述(https://www.innovation.ch/personal/ronald/ntlm.html)。如果你能避免這三個電話。答案是否定的。你應該問更具體的問題。 – andih

回答

0

發生異常是因爲InputStreamBody不可重複(特別是對於大型流)。一般的InputStream只能讀取一次。

FileBody是可重複的,因爲文件可以被多次讀取。

重複讀取的一個原因可能是(NTLM)授權(未檢查此)。

您可以通過在實際請求和設置/發送標頭之前執行前兩個NTML授權步驟來避免此問題,但這並不能解決問題,因爲網絡可能不夠可靠,必須重試無論如何。

你基本上有兩種選擇:

  1. 使用可重複ContentBody實現只喜歡FileBody或自己重複ContentBody實例。
  2. 確保請求不需要重試。

請注意後者並不總是可能。如前所述,可以避免由於驗證失敗而導致的請求重試,但由於I/O錯誤導致的重試不能。

+0

是否意味着我們不能使用NTLM身份驗證使用REST服務將文檔作爲流發佈,還是僅限於httpClient?是否有任何其他REST客戶端API可以像Jersey或其他任何其他的那樣促進它?如果發佈爲流是不可能的,因爲它本質上是不可重複的,那麼InputStreamBody將用作使用httpClient的倍數? – sab123

+0

它與NTLM或客戶端限制無關。客戶端支持發佈流,只要它們是可重複的,就像'FileBody'一樣,它也是作爲流發送的。 'InputStream'和'File'之間的區別在於''File''可以實現類似隨機訪問的事情,即跳轉到給定點,而使用一般的'InputStreams'則不能。您還可以通過預先認證/授權請求來克服授權內容(而不是特定於NTLM),但您仍然必須處理IO錯誤。只是如果你想以這種方式使用它,你必須做一些工作。 – andih

+0

感謝Andih的迴應。我認爲filebody在內存中加載整個文件,然後將其作爲請求的一部分發送。如果filebody在內部使用流,那麼它應該沒問題。我們有一個等效的上傳服務,它使用SOAP(基本認證)來上傳文件,並且正在發送啓用了MTOM的inputStream並且它正在工作。在當前的情況下,我們有REST,並試圖找出inputStream是否可以按照我們在SOAP中所做的相同方式發送到REST,而無需創建臨時文件。 – sab123