HttpClient
一 簡介
1.儘管java.net包提供了基本經過HTTP訪問資源的功能,但它沒有提供全面的靈活性和其它不少應用程序須要的功能。HttpClient就是尋求彌補這項空白的組件,經過提供一個有效的,保持更新的,功能豐富的軟件包來實現客戶端最新的HTTP標準和建議。
爲擴展而設計,同時爲基本的HTTP協議提供強大的支持,HttpClient組件也許就是構建HTTP客戶端應用程序,好比web瀏覽器,web服務端,利用或擴展HTTP協議進行分佈式通訊的系統的開發人員的關注點。
2.HttpClient不是一個瀏覽器。它是一個客戶端的HTTP通訊實現庫。HttpClient的目標是發送和接收HTTP報文。HttpClient不會去緩存內容,執行嵌入在HTML頁面中的javascript代碼,猜想內容類型,從新格式化請求/重定向URI,或者其它和HTTP運輸無關的功能。javascript
二 使用
1.執行請求
(1)HttpClient最重要的功能是執行HTTP方法。一個HTTP方法的執行包含一個或多個HTTP請求/HTTP響應交換,一般由HttpClient的內部來處理。而指望用戶提供一個要執行的請求對象,而HttpClient指望傳輸請求到目標服務器並返回對應的響應對象,或者當執行不成功時拋出異常。
一個很簡單的請求執行過程的示例:html
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) { } }
(2)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包含一個協議模式,主機名稱,可選的端口,資源路徑,可選的查詢和可選的片斷。
HttpClient提供不少工具方法來簡化建立和修改執行URI。
a.使用URIUtils工具類java
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=
b.查詢字符串也能夠從獨立的參數中來生成web
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=
(3)HTTP響應
HTTP響應是由服務器在接收和解釋請求報文以後返回發送給客戶端的報文。響應報文的第一行包含了協議版本,以後是數字狀態碼和相關聯的文本段。apache
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瀏覽器
(4)處理報文頭部
一個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"tomcat
三 使用HttpClient發送請求、接收響應服務器
1.通常須要以下幾步:
(1) 建立HttpClient對象。
(2)建立請求方法的實例,並指定請求URL。若是須要發送GET請求,建立HttpGet對象;若是須要發送POST請求,建立HttpPost對象。
(3) 若是須要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HetpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。
(4) 調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse。
(5) 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可經過該對象獲取服務器的響應內容。
(6) 釋放鏈接。不管執行方法是否成功,都必須釋放鏈接dom
2.使用httpClient的兩種方式:
(1)第一種:
public class HttpClientExample { public static void main(String args[]) throws IOException{ List<NameValuePair> formparams=new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("account","")); formparams.add(new BasicNameValuePair("password","")); HttpEntity reqEntity=new UrlEncodedFormEntity(formparams,"utf-8"); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(5000) .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) .build(); HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://baidu.com"); post.setEntity(reqEntity); post.setConfig(requestConfig); HttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity resEntity = response.getEntity(); String message = EntityUtils.toString(resEntity, "utf-8"); System.out.println(message); } else { System.out.println("請求失敗"); } } }
(2)第二種:這種方式是用了一個http的鏈接池,同時使用httpbuilder構造合適的http方法
public class HttpClientExample2 { private static PoolingHttpClientConnectionManager connectionManager = null; private static HttpClientBuilder httpBulder = null; private static RequestConfig requestConfig = null; private static int MAXCONNECTION = 10; private static int DEFAULTMAXCONNECTION = 5; private static String IP = "cnivi.com.cn"; private static int PORT = 80; static { //設置http的狀態參數 requestConfig = RequestConfig.custom() .setSocketTimeout(5000) .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) .build(); HttpHost target = new HttpHost(IP, PORT); connectionManager = new PoolingHttpClientConnectionManager(); connectionManager.setMaxTotal(MAXCONNECTION); connectionManager.setDefaultMaxPerRoute(DEFAULTMAXCONNECTION); connectionManager.setMaxPerRoute(new HttpRoute(target), 20); httpBulder = HttpClients.custom(); httpBulder.setConnectionManager(connectionManager); } public static CloseableHttpClient getConnection() { CloseableHttpClient httpClient = httpBulder.build(); httpClient = httpBulder.build(); return httpClient; } public static HttpUriRequest getRequestMethod(Map<String, String> map, String url, String method) { List<NameValuePair> params = new ArrayList<NameValuePair>(); Set<Map.Entry<String, String>> entrySet = map.entrySet(); for (Map.Entry<String, String> e : entrySet) { String name = e.getKey(); String value = e.getValue(); NameValuePair pair = new BasicNameValuePair(name, value); params.add(pair); } HttpUriRequest reqMethod = null; if ("post".equals(method)) { reqMethod = RequestBuilder.post().setUri(url) .addParameters(params.toArray(new BasicNameValuePair[params.size()])) .setConfig(requestConfig).build(); } else if ("get".equals(method)) { reqMethod = RequestBuilder.get().setUri(url) .addParameters(params.toArray(new BasicNameValuePair[params.size()])) .setConfig(requestConfig).build(); } return reqMethod; } public static void main(String args[]) throws IOException { Map<String, String> map = new HashMap<String, String>(); map.put("account", ""); map.put("password", ""); HttpClient client = getConnection(); HttpUriRequest post = getRequestMethod(map, "http://baidu.com", "post"); HttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity entity = response.getEntity(); String message = EntityUtils.toString(entity, "utf-8"); System.out.println(message); } else { System.out.println("請求失敗"); } } }
3.再看一個例子
import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.junit.Test; import javax.net.ssl.SSLContext; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; public class HttpClientExample3{ @Test public void jUnitTest() { get(); } /** * HttpClient鏈接SSL */ public void ssl() { CloseableHttpClient httpclient = null; try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream instream = new FileInputStream(new File("d:\\tomcat.keystore")); try { // 加載keyStore d:\\tomcat.keystore trustStore.load(instream, "123456".toCharArray()); } catch (CertificateException e) { e.printStackTrace(); } finally { try { instream.close(); } catch (Exception ignore) { } } // 相信本身的CA和全部自簽名的證書 SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build(); // 只容許使用TLSv1協議 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); // 建立http請求(get方式) HttpGet httpget = new HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action"); System.out.println("executing request" + httpget.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); System.out.println(EntityUtils.toString(entity)); EntityUtils.consume(entity); } } finally { response.close(); } } catch (IOException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } finally { if (httpclient != null) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * post方式提交表單(模擬用戶登陸請求) */ public void postForm() { // 建立默認的httpClient實例. CloseableHttpClient httpclient = HttpClients.createDefault(); // 建立httppost HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action"); // 建立參數隊列 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("username", "admin")); formparams.add(new BasicNameValuePair("password", "123456")); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); System.out.println("executing request " + httppost.getURI()); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("--------------------------------------"); System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8")); System.out.println("--------------------------------------"); } } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉鏈接,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 發送 post請求訪問本地應用並根據傳遞參數不一樣返回不一樣結果 */ public void post() { // 建立默認的httpClient實例. CloseableHttpClient httpclient = HttpClients.createDefault(); // 建立httppost HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action"); // 建立參數隊列 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("type", "house")); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); System.out.println("executing request " + httppost.getURI()); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("--------------------------------------"); System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8")); System.out.println("--------------------------------------"); } } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉鏈接,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 發送 get請求 */ public void get() { CloseableHttpClient httpclient = HttpClients.createDefault(); try { // 建立httpget. HttpGet httpget = new HttpGet("http://www.baidu.com/"); System.out.println("executing request " + httpget.getURI()); // 執行get請求. CloseableHttpResponse response = httpclient.execute(httpget); try { // 獲取響應實體 HttpEntity entity = response.getEntity(); System.out.println("--------------------------------------"); // 打印響應狀態 System.out.println(response.getStatusLine()); if (entity != null) { // 打印響應內容長度 System.out.println("Response content length: " + entity.getContentLength()); // 打印響應內容 System.out.println("Response content: " + EntityUtils.toString(entity)); } System.out.println("------------------------------------"); } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉鏈接,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } }
還能夠參考一下這個:
public String getResponseXMLFromURL(String url){ String result = null; CloseableHttpResponse response = null; try { response = getHttpResponse(url); result = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET); EntityUtils.consume(response.getEntity()); } catch (IOException e) { LOG.error("when getResponseXMLFromURL got an error"+e.getMessage()); Exceptions.throwException(e); }finally{ try { if(response!=null){ response.close(); } } catch (IOException e) { LOG.error("when getResponseXMLFromURL got an error" + e.getMessage()); } } return result; } public CloseableHttpResponse getHttpResponse(String url) throws IOException { PoolingHttpClientConnectionManager cm = HttpConnectionManager.getInstance(); int timeout = 5; RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(timeout * 1000 * 60) .setSocketTimeout(timeout * 1000 * 60).build(); return httpClientCreator(cm,requestConfig).execute(new HttpGet(url)); } public CloseableHttpClient httpClientCreator(PoolingHttpClientConnectionManager cm,RequestConfig requestConfig){ if(null != requestConfig){ return HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).setProxy(new HttpHost(proxyUrl, Integer.valueOf(proxyPort))).build(); } else { return HttpClients.custom().setConnectionManager(cm).setProxy(new HttpHost(proxyUrl, Integer.valueOf(proxyPort))).build(); }
參考:http://www.cnblogs.com/lyy-2016/p/6388663.html