[英](java) HttpEntity.getContent() outputs limited InputStream (8192b / 7748b) … I'm trying to download a 2.4MB file
[英]Can I skip implementing HttpEntity#getContent()?
我打算將結構化數據寫入通過HTTP客戶端訪問的資源。 用於執行此操作的API(針對JSON,YAML,XML)通常使我將它們傳遞給他們的OutputStream
傳遞給它們-它們沒有給我InputStream
。
不管是好是壞,Apache HTTP Components HttpClient是此處使用的客戶端。 (我們使用的其他庫依賴於它。在大多數情況下,這並不完全不好,至少不強迫我們使用怪異的線程本地hack來獲得理智的行為,這與java.net.URL
不同。)
發出請求時, HttpEntityEnclosingRequestBase
(在HttpClient中)迫使我設置HttpEntity
以將任何數據發送到服務器。 HttpEntity
似乎迫使我實現getContent()
,並返回InputStream
。
我沒有InputStream
,所以我不得不在兩種解決方法之間進行選擇:
A)將所有數據序列化為內存中的字節數組,然后再次將其全部流回。 我不想這樣做,因為通常情況下,數據的序列化形式要比數據本身占用更多的內存,並且在某些情況下,我們甚至根本不將其存儲在內存中,因此這會自找麻煩。
B)創建一個Pipe
。 旋轉第二個線程以將該對象寫入管道的OutputStream
末端。 返回InputStream
結束。 實際上,這不能在HttpEntity
本身中完成,因為HttpEntity
不知道何時不再需要數據流。 (這可以引起人們有根據的猜測,當您到達流的末尾時就已經完成了,但是如果與服務器的連接中途掉線了,您將永遠保持管道暢通。)這意味着我最終將解決方法轉移到每個建立連接的地方,這是很多結構上的重復。
這些變通辦法都不是很好,但是我猜(B)的“狗屎少”,因為它至少不會在傳輸大對象時使整個應用程序崩潰。
就我所知:
public class WriteLogicEntity extends AbstractHttpEntity {
private final WriteLogic writeLogic;
public InputStreamEntity(WriteLogic writeLogic) {
this(instream, null);
}
public InputStreamEntity(WriteLogic writeLogic,
ContentType contentType) {
this.writeLogic = writeLogic;
if(contentType != null) {
this.setContentType(contentType.toString());
}
}
@Override
public boolean isRepeatable() {
// We could enforce that all WriteLogic be repeatable
// or add a similar method there, but at least for now,
// assuming it isn't repeatable is safe.
return false;
}
@Override
public long getContentLength() {
// We really don't know.
return -1L;
}
@Override
public InputStream getContent() throws IOException {
//TODO: What do we do here?
}
@Override
public void writeTo(OutputStream outstream) throws IOException {
writeLogic.withOutputStream(outstream);
}
@Override
public boolean isStreaming() {
return true; //TODO: Verify this choice
}
}
public interface WriteLogic {
void withOutputStream(OutputStream stream) throws IOException;
}
現在我想知道getContent()
可以拋出UnsupportedOperationException。 當然,在發出請求時,他們還是會使用writeTo()
,對吧? 好吧,我不知道。 即使它可以在一個實驗中工作,也不能保證我無法通過某種請求來要求調用getContent()
。
因此,我想知道是否有人比我更了解此庫,所以可以調用它-跳過實現此方法是否安全?
(此getContent()
方法似乎不應該包含在API中。或者應該對其進行記錄,以至少允許我以某種方式實現它。我打算無論如何都要提交一個錯誤,因為這樣做非常不便在您嘗試編寫請求時被迫提供InputStream
。)
如果實體內容不能表示為InputStream,則getContent
方法可以引發UnsupportedOperationException。 在內部,HttpClient使用writeTo
將實體內容流式傳輸到基礎HTTP連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.