httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)
生活随笔
收集整理的這篇文章主要介紹了
httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
(第一章 上)
前言
超文本傳輸協(xié)議(HTTP)也許是當今互聯(lián)網(wǎng)上使用的最重要的協(xié)議了。Web服務,有網(wǎng)絡功能的設備和網(wǎng)絡計算的發(fā)展,都持續(xù)擴展了HTTP協(xié)議的角色,超越了用戶使用的Web瀏覽器范疇,同時,也增加了需要HTTP協(xié)議支持的應用程序的數(shù)量。
盡管java.net包提供了基本通過HTTP訪問資源的功能,但它沒有提供全面的靈活性和其它很多應用程序需要的功能。HttpClient就是尋求彌補這項空白的組件,通過提供一個有效的,保持更新的,功能豐富的軟件包來實現(xiàn)客戶端最新的HTTP標準和建議。
為擴展而設計,同時為基本的HTTP協(xié)議提供強大的支持,HttpClient組件也許就是構建HTTP客戶端應用程序,比如web瀏覽器,web服務端,利用或擴展HTTP協(xié)議進行分布式通信的系統(tǒng)的開發(fā)人員的關注點。
1. HttpClient的范圍基于HttpCore[http://hc.apache.org/httpcomponents-core/index.html]的客戶端HTTP運輸實現(xiàn)庫
基于經(jīng)典(阻塞)I/O
內(nèi)容無關
2. 什么是HttpClient不能做的HttpClient不是一個瀏覽器。它是一個客戶端的HTTP通信實現(xiàn)庫。HttpClient的目標是發(fā)送和接收HTTP報文。 HttpClient不會去緩存內(nèi)容,執(zhí)行嵌入在HTML頁面中的javascript代碼,猜測內(nèi)容類型,重新格式化請求/重定向URI,或者其它和 HTTP運輸無關的功能。
第一章 基礎1.1 執(zhí)行請求HttpClient最重要的功能是執(zhí)行HTTP方法。一個HTTP方法的執(zhí)行包含一個或多個HTTP請求/HTTP響應交換,通常由 HttpClient的內(nèi)部來處理。而期望用戶提供一個要執(zhí)行的請求對象,而HttpClient期望傳輸請求到目標服務器并返回對應的響應對象,或者當執(zhí)行不成功時拋出異常。
很自然地,HttpClient API的主要切入點就是定義描述上述規(guī)約的HttpClient接口。
這里有一個很簡單的請求執(zhí)行過程的示例:
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協(xié)議版本的請求行。
HttpClient支持所有定義在HTTP/1.1版本中的HTTP方法:GET,HEAD,POST,PUT,DELETE,TRACE和 OPTIONS。對于每個方法類型都有一個特殊的類:HttpGet,HttpHead,HttpPost,HttpPut,HttpDelete,HttpTrace和HttpOptions。
請求的URI是統(tǒng)一資源定位符,它標識了應用于哪個請求之上的資源。HTTP請求URI包含一個協(xié)議模式,主機名稱,可選的端口,資源路徑,可選的查詢和可選的片段。
HttpGet httpget = new HttpGet(
"http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");
HttpClient提供很多工具方法來簡化創(chuàng)建和修改執(zhí)行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());
輸出內(nèi)容為:
http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
查詢字符串也可以從獨立的參數(shù)中來生成:
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());
輸出內(nèi)容為:
http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
1.1.2 HTTP響應HTTP響應是由服務器在接收和解釋請求報文之后返回發(fā)送給客戶端的報文。響應報文的第一行包含了協(xié)議版本,之后是數(shù)字狀態(tài)碼和相關聯(lián)的文本段。
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());
輸出內(nèi)容為:
HTTP/1.1
200
OK
HTTP/1.1 200 OK
1.1.3 處理報文頭部一個HTTP報文可以包含很多描述如內(nèi)容長度,內(nèi)容類型等信息屬性的頭部信息。
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);
輸出內(nèi)容為:
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());
}
輸出內(nèi)容為:
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);
}
}
輸出內(nèi)容為:
c1 = a
path=/
domain=localhost
c2 = b
path=/
c3 = c
domain=localhost
1.1.4 HTTP實體HTTP報文可以攜帶和請求或響應相關的內(nèi)容實體。實體可以在一些請求和響應中找到,因為它們也是可選的。使用了實體的請求被稱為封閉實體請求。 HTTP規(guī)范定義了兩種封閉實體的方法:POST和PUT。響應通常期望包含一個內(nèi)容實體。這個規(guī)則也有特例,比如HEAD方法的響應和204 No Content,304 Not Modified和205 Reset Content響應。
HttpClient根據(jù)其內(nèi)容出自何處區(qū)分三種類型的實體:
streamed流式:內(nèi)容從流中獲得,或者在運行中產(chǎn)生。特別是這種分類包含從HTTP響應中獲取的實體。流式實體是不可重復生成的。
self-contained自我包含式:內(nèi)容在內(nèi)存中或通過獨立的連接或其它實體中獲得。自我包含式的實體是可以重復生成的。這種類型的實體會經(jīng)常用于封閉HTTP請求的實體。
wrapping包裝式:內(nèi)容從另外一個實體中獲得。
當從一個HTTP響應中獲取流式內(nèi)容時,這個區(qū)別對于連接管理很重要。對于由應用程序創(chuàng)建而且只使用HttpClient發(fā)送的請求實體,流式和自我包含式的不同就不那么重要了。這種情況下,建議考慮如流式這種不能重復的實體,和可以重復的自我包含式實體。
1.1.4.1 重復實體實體可以重復,意味著它的內(nèi)容可以被多次讀取。這就僅僅是自我包含式的實體了(像ByteArrayEntity或StringEntity)。
1.1.4.2 使用HTTP實體因為一個實體既可以代表二進制內(nèi)容又可以代表字符內(nèi)容,它也支持字符編碼(支持后者也就是字符內(nèi)容)。
實體是當使用封閉內(nèi)容執(zhí)行請求,或當請求已經(jīng)成功執(zhí)行,或當響應體結(jié)果發(fā)功到客戶端時創(chuàng)建的。
要從實體中讀取內(nèi)容,可以通過HttpEntity#getContent()方法從輸入流中獲取,這會返回一個 java.io.InputStream對象,或者提供一個輸出流到HttpEntity#writeTo(OutputStream)方法中,這會一次返回所有寫入到給定流中的內(nèi)容。
當實體通過一個收到的報文獲取時,HttpEntity#getContentType()方法和 HttpEntity#getContentLength()方法可以用來讀取通用的元數(shù)據(jù),如Content-Type和Content-Length 頭部信息(如果它們是可用的)。因為頭部信息Content-Type可以包含對文本MIME類型的字符編碼,比如text/plain或text /html,HttpEntity#getContentEncoding()方法用來讀取這個信息。如果頭部信息不可用,那么就返回長度-1,而對于內(nèi)容類型返回NULL。如果頭部信息Content-Type是可用的,那么就會返回一個Header對象。
當為一個傳出報文創(chuàng)建實體時,這個元數(shù)據(jù)不得不通過實體創(chuàng)建器來提供。
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);
輸出內(nèi)容為
Content-Type: text/plain; charset=UTF-8
17
UTF-8
important message
17
1.1.5 確保低級別資源釋放當完成一個響應實體,那么保證所有實體內(nèi)容已經(jīng)被完全消耗是很重要的,所以連接可以安全的放回到連接池中,而且可以通過連接管理器對后續(xù)的請求重用連接。處理這個操作的最方便的方法是調(diào)用HttpEntity#consumeContent()方法來消耗流中的任意可用內(nèi)容。HttpClient 探測到內(nèi)容流尾部已經(jīng)到達后,會立即會自動釋放低層連接,并放回到連接管理器。HttpEntity#consumeContent()方法調(diào)用多次也是安全的。
也可能會有特殊情況,當整個響應內(nèi)容的一小部分需要獲取,消耗剩余內(nèi)容而損失性能,還有重用連接的代價太高,則可以僅僅通過調(diào)用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 消耗實體內(nèi)容推薦消耗實體內(nèi)容的方式是使用它的HttpEntity#getContent()或 HttpEntity#writeTo(OutputStream)方法。HttpClient也自帶EntityUtils類,這會暴露出一些靜態(tài)方法,這些方法可以更加容易地從實體中讀取內(nèi)容或信息。代替直接讀取java.io.InputStream,也可以使用這個類中的方法以字符串/字節(jié)數(shù)組的形式獲取整個內(nèi)容體。然而,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
}
}
在一些情況下可能會不止一次的讀取實體。此時實體內(nèi)容必須以某種方式在內(nèi)存或磁盤上被緩沖起來。最簡單的方法是通過使用BufferedHttpEntity類來包裝源實體完成。這會引起源實體內(nèi)容被讀取到內(nèi)存的緩沖區(qū)中。在其它所有方式中,實體包裝器將會得到源實體。
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 生成實體內(nèi)容HttpClient提供一些類,它們可以用于生成通過HTTP連接獲得內(nèi)容的有效輸出流。為了封閉實體從HTTP請求中獲得的輸出內(nèi)容,那些類的實例可以和封閉如POST和PUT請求的實體相關聯(lián)。HttpClient為很多公用的數(shù)據(jù)容器,比如字符串,字節(jié)數(shù)組,輸入流和文件提供了一些類: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是不可重復的,因為它僅僅能從低層數(shù)據(jù)流中讀取一次內(nèi)容。通常來說,我們推薦實現(xiàn)一個定制的 HttpEntity類,這是自我包含式的,用來代替使用通用的InputStreamEntity。FileEntity也是一個很好的起點。
1.1.7.1 動態(tài)內(nèi)容實體通常來說,HTTP實體需要基于特定的執(zhí)行上下文來動態(tài)地生成。通過使用EntityTemplate實體類和ContentProducer接口,HttpClient提供了動態(tài)實體的支持。內(nèi)容生成器是按照需求生成它們內(nèi)容的對象,將它們寫入到一個輸出流中。它們是每次被請求時來生成內(nèi)容。所以用EntityTemplate創(chuàng)建的實體通常是自我包含而且可以重復的。
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);
轉(zhuǎn)載于:https://www.cnblogs.com/astroboyx/archive/2011/09/20/2739850.html
總結(jié)
以上是生活随笔為你收集整理的httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 下使用Java连接 mysq
- 下一篇: 链表应用——多项式相加