【HttpClient4.5中文教程】【第一章 :基礎】1.1運行請求(二)


很多其它HttpClient4.5中文教程請查看點擊打開鏈接

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

1.1.4.HTTP實體(HTTP Entity)

HTTP報文可以攜帶與請求或對應相關聯的內容實體。實體存在於某些請求、響應中,它門是可選的。

使用實體的請求被稱為內含實體請求【譯者:原文為entity enclosing requests。我把它翻譯為 內含實體請求】

HTTP規范定義了兩種內含實體請求。POST和PUT。而響應總是內含實體。

但有些響應不符合這一規則,比方,對HEAD方法的響應和狀態為204 No Content, 304 Not Modified, 205 Reset Content的響應。

根據實體的內容來源,HttpClient區分出三種實體:
流式實體(streamed):內容來源於一個流。或者在執行中產生【譯者:原文為generated on the fly】。特別的,這個類別包含從響應中接收到的實體。

流式實體不可反復。
自包括實體(self-contained):在內存中的內容或者通過獨立的連接/其它實體獲得的內容。自包括實體是可反復的。這類實體大部分是HTTP內含實體請求。
包裝實體(wrapping):從另外一個實體中獲取內容。



1.1.4.1 可反復實體

一個實體可以被反復,意味着它的內容可以被讀取多次。它僅可能是自包括實體(像ByteArrayEntity或StringEntity)


1.1.4.2 使用HTTP實體

因為一個實體可以表現為二進制和字符內容,它支持二進制編碼(為了支持后者。即字符內容)。

實體將會在一些情況下被創建:當運行一個含有內容的請求時或者當請求成功。響應體作為結果返回給client時。為了讀取實體的內容。能夠通過HttpEntity#getContent() 方法取出輸入流。返回一個java.io.InputStream,或者提供一個輸出流給HttpEntity#writeTo(OutputStream) 方法,它將會返回寫入給定流的全部內容。

當實體內部含有信息時,使用HttpEntity#getContentType()和HttpEntity#getContentLength()方法將會讀取一些主要的元數據,比方Content-Type和Content-Length這種首部(假設他們可用的話)。因為Content-Type首部可以包括文本MIME類型(像 text/plain 或text/html),它也包括了與MIME類型相相應的字符編碼。HttpEntity#getContentEncoding()方法被用來讀取這些字符編碼。假設相應的首部不存在,則Content-Length的返回值為-1,Content-Type返回值為NULL。假設Content-Type是可用的,一個Header類的對象將會返回。


當我們構建一個具有可用信息的實體時,元數據將會被實體構建器提供。【譯者:我理解的是。如以下樣例中的長度,並沒有聲明,可是可用,是構建器生成的】

StringEntity myEntity = new StringEntity("important message",
                          ContentType.create("text/plain", "UTF-8"));
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);

輸出:
Content-Type: text/plain; charset=utf-8
17
important message

17


1.1.5.確保釋放低級別的資源

為了確保正確的釋放系統資源,你必須關掉與實體與實體相關的的內容流。還必須關掉響應本身。
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
     HttpEntity entity = response.getEntity();
     if (entity != null) {
        InputStream instream = entity.getContent();
        try {
            // do something useful
        } finally {
            instream.close();
        }
   }
} finally {
     response.close();
}

關閉內容流和關閉響應的不同點是:前者將會通過消費實體內容保持潛在的連接。而后者迅速的關閉並丟棄連接。
請注意,一旦實體被HttpEntity#writeTo(OutputStream)方法成功地寫入時,也須要確保正確地釋放系統資源。假設方法獲得通過HttpEntity#getContent(),它也須要在一個finally子句中關閉流。


當使用實體時,你能夠使用EntityUtils#consume(HttpEntity)方法來確保實體內容全然被消費而且使潛在的流關閉。


某些情況。整個響應內容的只一小部分須要被取出。會使消費其它剩余內容的性能代價和連接可重用性代價太高,這時能夠通過關閉響應來終止內容流。

【譯者:樣例中能夠看出,實體輸入流只讀取了兩個字節,就關閉了響應,也就是按需讀取,而不是讀取所有響應】

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
        InputStream instream = entity.getContent();
    int byteOne = instream.read();
        int byteTwo = instream.read();
    // Do not need the rest
}
} finally {
    response.close();
}

這樣,連接將不會被重用,它分配的全部級別的資源將會被解除。


1.1.6.消費實體內容

為了消費實體內容,推薦的方式是使用HttpEntity#getContent()或者 HttpEntity#writeTo(OutputStream)方法。HttpClient也提供了一個EntityUtils類,它有幾個靜態方法更easy的從實體中讀取內容或信息。

代替了直接讀取java.io.InputStream,你能夠通過這個類的方法取出所有內容體並放入一個String 中或者byte數組中。

但是,強烈不建議使用EntityUtils,除非響應實體來自於信任的HTTPserver而且知道它的長度。【譯者:】

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
        long len = entity.getContentLength();
        if (len != -1 && len < 2048) {
             System.out.println(EntityUtils.toString(entity));
    } else {
        // Stream content out
    }
}
} finally {
    response.close();
}


在某些情況下,多次讀取實體內容是必要的。在這樣的情況下,實體內容必須以一些方式緩沖,內存或者硬盤中。為了達到這個目的,最簡單的方法是把原始的實體用BufferedHttpEntity類包裝起來。這將會使原始實體的內容讀入一個in-memory緩沖區。

全部方式的實體包裝都是代表最原始的那個實體。

CloseableHttpResponse response = <...>
HttpEntity entity = response.getEntity();
if (entity != null) {
    entity = new BufferedHttpEntity(entity);
}

==================總結=====================

1.經過前面兩節的學習,你已經掌握HttpClient4.5的基本使用方法了~趕快去試一下吧~

   【HttpClient4.5實訓】一.GET請求訪問新浪網(非原文教程)點擊打開鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM