httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)
生活随笔
收集整理的這篇文章主要介紹了
httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
(第一章 上)
前言
超文本傳輸協議(HTTP)也許是當今互聯網上使用的最重要的協議了。Web服務,有網絡功能的設備和網絡計算的發展,都持續擴展了HTTP協議的角色,超越了用戶使用的Web瀏覽器范疇,同時,也增加了需要HTTP協議支持的應用程序的數量。
盡管java.net包提供了基本通過HTTP訪問資源的功能,但它沒有提供全面的靈活性和其它很多應用程序需要的功能。HttpClient就是尋求彌補這項空白的組件,通過提供一個有效的,保持更新的,功能豐富的軟件包來實現客戶端最新的HTTP標準和建議。
為擴展而設計,同時為基本的HTTP協議提供強大的支持,HttpClient組件也許就是構建HTTP客戶端應用程序,比如web瀏覽器,web服務端,利用或擴展HTTP協議進行分布式通信的系統的開發人員的關注點。
1. HttpClient的范圍基于HttpCore[http://hc.apache.org/httpcomponents-core/index.html]的客戶端HTTP運輸實現庫
基于經典(阻塞)I/O
內容無關
2. 什么是HttpClient不能做的HttpClient不是一個瀏覽器。它是一個客戶端的HTTP通信實現庫。HttpClient的目標是發送和接收HTTP報文。 HttpClient不會去緩存內容,執行嵌入在HTML頁面中的javascript代碼,猜測內容類型,重新格式化請求/重定向URI,或者其它和 HTTP運輸無關的功能。
第一章 基礎1.1 執行請求HttpClient最重要的功能是執行HTTP方法。一個HTTP方法的執行包含一個或多個HTTP請求/HTTP響應交換,通常由 HttpClient的內部來處理。而期望用戶提供一個要執行的請求對象,而HttpClient期望傳輸請求到目標服務器并返回對應的響應對象,或者當執行不成功時拋出異常。
很自然地,HttpClient API的主要切入點就是定義描述上述規約的HttpClient接口。
這里有一個很簡單的請求執行過程的示例:
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://localhost/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int l;
byte[] tmp = new byte[2048];
while ((l = instream.read(tmp)) != -1) {
}
}
1.1.1 HTTP請求所有HTTP請求有一個組合了方法名,請求URI和HTTP協議版本的請求行。
HttpClient支持所有定義在HTTP/1.1版本中的HTTP方法:GET,HEAD,POST,PUT,DELETE,TRACE和 OPTIONS。對于每個方法類型都有一個特殊的類:HttpGet,HttpHead,HttpPost,HttpPut,HttpDelete,HttpTrace和HttpOptions。
請求的URI是統一資源定位符,它標識了應用于哪個請求之上的資源。HTTP請求URI包含一個協議模式,主機名稱,可選的端口,資源路徑,可選的查詢和可選的片段。
HttpGet httpget = new HttpGet(
"http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");
HttpClient提供很多工具方法來簡化創建和修改執行URI。
URI也可以編程來拼裝:
URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
"q=httpclient&btnG=Google+Search&aq=f&oq=", null);
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());
輸出內容為:
http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
查詢字符串也可以從獨立的參數中來生成:
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("q", "httpclient"));
qparams.add(new BasicNameValuePair("btnG", "Google Search"));
qparams.add(new BasicNameValuePair("aq", "f"));
qparams.add(new BasicNameValuePair("oq", null));
URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
URLEncodedUtils.format(qparams, "UTF-8"), null);
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());
輸出內容為:
http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
1.1.2 HTTP響應HTTP響應是由服務器在接收和解釋請求報文之后返回發送給客戶端的報文。響應報文的第一行包含了協議版本,之后是數字狀態碼和相關聯的文本段。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
System.out.println(response.getProtocolVersion());
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.getStatusLine().getReasonPhrase());
System.out.println(response.getStatusLine().toString());
輸出內容為:
HTTP/1.1
200
OK
HTTP/1.1 200 OK
1.1.3 處理報文頭部一個HTTP報文可以包含很多描述如內容長度,內容類型等信息屬性的頭部信息。
HttpClient提供獲取,添加,移除和枚舉頭部信息的方法。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
Header h1 = response.getFirstHeader("Set-Cookie");
System.out.println(h1);
Header h2 = response.getLastHeader("Set-Cookie");
System.out.println(h2);
Header[] hs = response.getHeaders("Set-Cookie");
System.out.println(hs.length);
輸出內容為:
Set-Cookie: c1=a; path=/; domain=localhost
Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
獲得給定類型的所有頭部信息最有效的方式是使用HeaderIterator接口。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
HeaderIterator it = response.headerIterator("Set-Cookie");
while (it.hasNext()) {
System.out.println(it.next());
}
輸出內容為:
Set-Cookie: c1=a; path=/; domain=localhost
Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
它也提供解析HTTP報文到獨立頭部信息元素的方法方法。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator("Set-Cookie"));
while (it.hasNext()) {
HeaderElement elem = it.nextElement();
System.out.println(elem.getName() + " = " + elem.getValue());
NameValuePair[] params = elem.getParameters();
for (int i = 0; i < params.length; i++) {
System.out.println(" " + params);
}
}
輸出內容為:
c1 = a
path=/
domain=localhost
c2 = b
path=/
c3 = c
domain=localhost
1.1.4 HTTP實體HTTP報文可以攜帶和請求或響應相關的內容實體。實體可以在一些請求和響應中找到,因為它們也是可選的。使用了實體的請求被稱為封閉實體請求。 HTTP規范定義了兩種封閉實體的方法:POST和PUT。響應通常期望包含一個內容實體。這個規則也有特例,比如HEAD方法的響應和204 No Content,304 Not Modified和205 Reset Content響應。
HttpClient根據其內容出自何處區分三種類型的實體:
streamed流式:內容從流中獲得,或者在運行中產生。特別是這種分類包含從HTTP響應中獲取的實體。流式實體是不可重復生成的。
self-contained自我包含式:內容在內存中或通過獨立的連接或其它實體中獲得。自我包含式的實體是可以重復生成的。這種類型的實體會經常用于封閉HTTP請求的實體。
wrapping包裝式:內容從另外一個實體中獲得。
當從一個HTTP響應中獲取流式內容時,這個區別對于連接管理很重要。對于由應用程序創建而且只使用HttpClient發送的請求實體,流式和自我包含式的不同就不那么重要了。這種情況下,建議考慮如流式這種不能重復的實體,和可以重復的自我包含式實體。
1.1.4.1 重復實體實體可以重復,意味著它的內容可以被多次讀取。這就僅僅是自我包含式的實體了(像ByteArrayEntity或StringEntity)。
1.1.4.2 使用HTTP實體因為一個實體既可以代表二進制內容又可以代表字符內容,它也支持字符編碼(支持后者也就是字符內容)。
實體是當使用封閉內容執行請求,或當請求已經成功執行,或當響應體結果發功到客戶端時創建的。
要從實體中讀取內容,可以通過HttpEntity#getContent()方法從輸入流中獲取,這會返回一個 java.io.InputStream對象,或者提供一個輸出流到HttpEntity#writeTo(OutputStream)方法中,這會一次返回所有寫入到給定流中的內容。
當實體通過一個收到的報文獲取時,HttpEntity#getContentType()方法和 HttpEntity#getContentLength()方法可以用來讀取通用的元數據,如Content-Type和Content-Length 頭部信息(如果它們是可用的)。因為頭部信息Content-Type可以包含對文本MIME類型的字符編碼,比如text/plain或text /html,HttpEntity#getContentEncoding()方法用來讀取這個信息。如果頭部信息不可用,那么就返回長度-1,而對于內容類型返回NULL。如果頭部信息Content-Type是可用的,那么就會返回一個Header對象。
當為一個傳出報文創建實體時,這個元數據不得不通過實體創建器來提供。
StringEntity myEntity = new StringEntity("important message",
"UTF-8");
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.getContentCharSet(myEntity));
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);
輸出內容為
Content-Type: text/plain; charset=UTF-8
17
UTF-8
important message
17
1.1.5 確保低級別資源釋放當完成一個響應實體,那么保證所有實體內容已經被完全消耗是很重要的,所以連接可以安全的放回到連接池中,而且可以通過連接管理器對后續的請求重用連接。處理這個操作的最方便的方法是調用HttpEntity#consumeContent()方法來消耗流中的任意可用內容。HttpClient 探測到內容流尾部已經到達后,會立即會自動釋放低層連接,并放回到連接管理器。HttpEntity#consumeContent()方法調用多次也是安全的。
也可能會有特殊情況,當整個響應內容的一小部分需要獲取,消耗剩余內容而損失性能,還有重用連接的代價太高,則可以僅僅通過調用HttpUriRequest#abort()方法來中止請求。
HttpGet httpget = new HttpGet("http://localhost/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int byteOne = instream.read();
int byteTwo = instream.read();
// Do not need the rest
httpget.abort();
}
連接不會被重用,但是由它持有的所有級別的資源將會被正確釋放。
1.1.6 消耗實體內容推薦消耗實體內容的方式是使用它的HttpEntity#getContent()或 HttpEntity#writeTo(OutputStream)方法。HttpClient也自帶EntityUtils類,這會暴露出一些靜態方法,這些方法可以更加容易地從實體中讀取內容或信息。代替直接讀取java.io.InputStream,也可以使用這個類中的方法以字符串/字節數組的形式獲取整個內容體。然而,EntityUtils的使用是強烈不鼓勵的,除非響應實體源自可靠的HTTP服務器和已知的長度限制。
HttpGet httpget = new HttpGet("http://localhost/");
HttpResponse response = httpclient.execute(httpget);
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
}
}
在一些情況下可能會不止一次的讀取實體。此時實體內容必須以某種方式在內存或磁盤上被緩沖起來。最簡單的方法是通過使用BufferedHttpEntity類來包裝源實體完成。這會引起源實體內容被讀取到內存的緩沖區中。在其它所有方式中,實體包裝器將會得到源實體。
HttpGet httpget = new HttpGet("http://localhost/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
entity = new BufferedHttpEntity(entity);
}
1.1.7 生成實體內容HttpClient提供一些類,它們可以用于生成通過HTTP連接獲得內容的有效輸出流。為了封閉實體從HTTP請求中獲得的輸出內容,那些類的實例可以和封閉如POST和PUT請求的實體相關聯。HttpClient為很多公用的數據容器,比如字符串,字節數組,輸入流和文件提供了一些類:StringEntity,ByteArrayEntity,InputStreamEntity和FileEntity。
File file = new File("somefile.txt");
FileEntity entity = new FileEntity(file, "text/plain; charset=\"UTF-8\"");
HttpPost httppost = new HttpPost("http://localhost/action.do");
httppost.setEntity(entity);
請注意InputStreamEntity是不可重復的,因為它僅僅能從低層數據流中讀取一次內容。通常來說,我們推薦實現一個定制的 HttpEntity類,這是自我包含式的,用來代替使用通用的InputStreamEntity。FileEntity也是一個很好的起點。
1.1.7.1 動態內容實體通常來說,HTTP實體需要基于特定的執行上下文來動態地生成。通過使用EntityTemplate實體類和ContentProducer接口,HttpClient提供了動態實體的支持。內容生成器是按照需求生成它們內容的對象,將它們寫入到一個輸出流中。它們是每次被請求時來生成內容。所以用EntityTemplate創建的實體通常是自我包含而且可以重復的。
ContentProducer cp = new ContentProducer() {
public void writeTo(OutputStream outstream) throws IOException {
Writer writer = new OutputStreamWriter(outstream, "UTF-8");
writer.write("<response>");
writer.write(" <content>");
writer.write(" important stuff");
writer.write(" </content>");
writer.write("</response>");
writer.flush();
}
};
HttpEntity entity = new EntityTemplate(cp);
HttpPost httppost = new HttpPost("http://localhost/handler.do");
httppost.setEntity(entity);
轉載于:https://www.cnblogs.com/astroboyx/archive/2011/09/20/2739850.html
總結
以上是生活随笔為你收集整理的httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 下使用Java连接 mysq
- 下一篇: 链表应用——多项式相加