HttpClient學習

 HttpClient學習

(1)下面列舉幾個主要的Http相關概念的類

類名 描述
HttpClient 建立請求客戶端
HttpGet 代表請求方法,類似的還有HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace,  HttpOptions等
HttpResponse 表示請求的響應(包括響應狀態、協議等頭信息,Header封裝各種頭信息,頭信息又包括HeaderElement,都可以採用迭代器的方式進行迭代讀取)
HttpEntity 表示相應的實體,用於存放傳送的內容,也就是body體,存在於request和response中,request只有post和put方法有,response中都有Entity,除了一些特殊情況不包含內容。Entity根據來源分爲三種:streamed,一次讀取;wrapping,從其他entity封裝;self-contained,從內存中讀取,可反覆讀。
URIBuilder 工具類用來生成url,主要是設置協議、域名和路徑,還有各種參數等

(2)HttpEntity的幾個主要函數

函數 描述
getContentType 獲取內容類型
getContentLength 獲取內容長度
getContent 獲取內容的輸入流InputStream

 

  1. HttpEntity entity=response.getEntity(); 
  2.  
  3.             System.out.println(entity.getContentType()); 
  4.  
  5.             System.out.println(entity.getContentLength()); 
  6.  
  7.             InputStream in=entity.getContent();//直接獲取輸入流,一次讀取 

(3)HttpEntity直接獲取的streamed流

  1. 只能讀取一次,如果想讀取多次,就要進行緩存,利用wrapping方式將streamed進行包裝BufferedHttpEntity 
  2. BufferedHttpEntity bufEntity=new BufferedHttpEntity(entity);//通過構造形式封裝進緩存,可多次讀取 

(4)HttpEntity也可放在post和put方法的請求中

  1. 作爲請求傳遞的內容。內容可以是文件,也可以提交form參數 
  2.             File file=new File("out.txt"); 
  3.  
  4.             FileEntity fileEntity=new FileEntity(file, ContentType.create("text/plain""UTF-8"));//文件內容輸入 
  5.  
  6.   
  7.  
  8.             List<NameValuePair> formparams = new ArrayList<NameValuePair>(); 
  9.  
  10.             formparams.add(new BasicNameValuePair("param1""value1")); 
  11.  
  12.             formparams.add(new BasicNameValuePair("param2""value2")); 
  13.  
  14.             UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8");//form表單內容輸入 
  15.  
  16.             HttpPost post=new HttpPost("http://www.baidu.com"); 
  17.  
  18.             post.setEntity(fileEntity); 

(5)response處理類最方便的是ResponseHandler類,它的功能是將entity轉化爲不同的內容格式

  1. ResponseHandler<byte[]> handler = new ResponseHandler<byte[]>() { 
  2.  
  3.               public byte[] handleResponse( 
  4.  
  5.                        HttpResponse response) throws ClientProtocolException, IOException { 
  6.  
  7.                    HttpEntity entity = response.getEntity(); 
  8.  
  9.                   if (entity != null) { 
  10.  
  11.                       return EntityUtils.toByteArray(entity); 
  12.  
  13.                   } else { 
  14.  
  15.                       return null
  16.  
  17.                   } 
  18.  
  19.               } 
  20.  
  21.           }; 
  22.  
  23.  
  24.  
  25.           byte[] response = httpclient.execute(httpget, handler); 
  26.  
  27.            ResponseHandler<String> handler1=new BasicResponseHandler(); 
  28.  
  29.            String response1= httpclient.execute(httpget,handler1);        

(6)request請求時可以設置一些http參數httpparam

和httpcontext相似,httpclient可以設置客戶端範圍的,httprequest也可以設置,但是請求範圍的。

參數名 描述
CoreProtocolPNames.PROTOCOL_VERSION='http.protocol.version' 協議版本
CoreProtocolPNames.HTTP_ELEMENT_CHARSET='http.protocol.element-charset' 協議元素編碼
CoreProtocolPNames.HTTP_CONTENT_CHARSET='http.protocol.content-charset' 協議內容編碼
CoreProtocolPNames.USER_AGENT='http.useragent' 用戶端,寫爬蟲的時候有用
CoreProtocolPNames.STRICT_TRANSFER_ENCODING='http.protocol.strict-transfer-encoding' (...
CoreProtocolPNames.USE_EXPECT_CONTINUE='http.protocol.expect-continue' ...
CoreProtocolPNames.WAIT_FOR_CONTINUE='http.protocol.wait-for-continue' ...

 

  1. httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,  
  2.  
  3.   HttpVersion.HTTP_1_0); // Default to HTTP 1.0 
  4.  
  5.   httpclient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET,  
  6.  
  7.      "UTF-8"); 
  8.  
  9.  
  10.  
  11.   HttpGet httpget = new HttpGet("http://www.google.com.hk/"); 
  12.  
  13.   httpget.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,  
  14.  
  15.       HttpVersion.HTTP_1_1); // Use HTTP 1.1 for this request only 
  16.  
  17.   httpget.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,  
  18.  
  19.       Boolean.FALSE); 

(7)httpclient完成了對connection的控制

但是上面的方法都沒有涉及連接的設置,這裏提供一些參數可以進行設置通過HttpParam設置

參數 描述
CoreConnectionPNames.SO_TIMEOUT='http.socket.timeout' 等待數據的最大時間,也就是兩段連續數據讀取之間的間隔
CoreConnectionPNames.TCP_NODELAY='http.tcp.nodelay' bool值,設置是否應用Naple算法,該算法最小化發送的包數,因此每個包很大,佔帶寬,有延遲
CoreConnectionPNames.SOCKET_BUFFER_SIZE='http.socket.buffer-size' 設置接發數據的緩衝區大小
CoreConnectionPNames.SO_LINGER='http.socket.linger' ...
CoreConnectionPNames.CONNECTION_TIMEOUT='http.connection.timeout' 設置連接超時
CoreConnectionPNames.STALE_CONNECTION_CHECK='http.connection.stalecheck' ...
CoreConnectionPNames.MAX_LINE_LENGTH='http.connection.max-line-length' 設置每行最大長度
CoreConnectionPNames.MAX_HEADER_COUNT='http.connection.max-header-count' 設置頭最大數量
ConnConnectionPNames.MAX_STATUS_LINE_GARBAGE='http.connection.max-status-line-garbage' ...

(8)實際應用的中,從連接池裏獲取連接是比較好的方法,連接池負責管理連接。

  1. BasicClientConnectionManager man=new BasicClientConnectionManager();//最基本的連接池,一次只維護一個連接 
  2.  
  3. System.out.println(httpclient.getConnectionManager().getClass());//輸出class org.apache.http.impl.conn.BasicClientConnectionManager 
  4.  
  5.  
  6.  
  7. //下面採用PoolingClientConnectionManager連接池管理,該連接池支持多線程操作     
  8.  
  9.    if(httpConnManger==null
  10.  
  11.   { 
  12.  
  13.      SchemeRegistry schemeRegistry = new SchemeRegistry(); 
  14.  
  15.      schemeRegistry.register( 
  16.  
  17.   new Scheme("http"80, PlainSocketFactory.getSocketFactory())); 
  18.  
  19.    httpConnManger=new PoolingClientConnectionManager(schemeRegistry); 
  20.  
  21.    httpConnManger.setMaxTotal(10); 
  22.  
  23.    httpConnManger.setDefaultMaxPerRoute(20); 
  24.  
  25.  
  26.  HttpParams params=new BasicHttpParams(); 
  27.  
  28.  params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIME); 
  29.  
  30.  HttpClient httpClient=new DefaultHttpClient(httpConnManger,params); 
  31.  
  32.  HttpGet httpGet=new HttpGet(urlAddr); 
  33.  
  34.  HttpResponse response; 
  35.  
  36. try { 
  37.  
  38.   response = httpClient.execute(httpGet); 
  39.  
  40. catch (ClientProtocolException e) { 
  41.  
  42.   log.error(e.getMessage()); 
  43.  
  44.  return null
  45.  
  46. catch (IOException e) { 
  47.  
  48.   log.error(e.getMessage()); 
  49.  
  50.  return null
  51.  

(9)需要代理的請求,設置HttpProxy

  1. HttpHost proxy = new HttpHost("127.0.0.1"8080"http"); 
  2.  
  3. DefaultHttpClient httpclient = new DefaultHttpClient(); 
  4.  
  5. httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); 
  6.  
  7. HttpHost target = new HttpHost("issues.apache.org"443"https"); 
  8.  
  9. HttpGet req = new HttpGet("/"); 
  10.  
  11. System.out.println("executing request to " + target + " via " + proxy); 
  12.  
  13. HttpResponse rsp = httpclient.execute(target, req); 
  14.  
  15. HttpEntity entity = rsp.getEntity(); 

(10)需要登錄驗證的請求

  1. httpclient.getCredentialsProvider().setCredentials( 
  2.  
  3.                   new AuthScope("localhost"443), 
  4.  
  5.                   new UsernamePasswordCredentials("username""password")); 
  6.  
  7.  
  8.  
  9.            HttpGet httpget = new HttpGet("https://localhost/protected"); 
  10.  
  11.  
  12.  
  13.            System.out.println("executing request" + httpget.getRequestLine()); 
  14.  
  15.            HttpResponse response = httpclient.execute(httpget); 
  16.  
  17.            HttpEntity entity = response.getEntity(); 
  18.  
  19.  
  20.  
  21.            System.out.println("----------------------------------------"); 
  22.  
  23.            System.out.println(response.getStatusLine()); 
  24.  
  25.           if (entity != null) { 
  26.  
  27.                System.out.println("Response content length: " + entity.getContentLength()); 
  28.  
  29.           } 
  30.  
  31.            EntityUtils.consume(entity); 
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章