簡體   English   中英

我可以跳過實現HttpEntity#getContent()嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM