基于HttpClient 4.5.2
-
執(zhí)行GET請求
CloseableHttpClient httpClient = HttpClients.custom() .build(); CloseableHttpResponse response = httpClient.execute(new HttpGet("https://www.baidu.com")); System.out.println(EntityUtils.toString(response.getEntity()));
-
執(zhí)行POST請求
- 提交form表單參數(shù)
CloseableHttpClient httpClient = HttpClients.custom() .build(); HttpPost httpPost = new HttpPost("https://www.explame.com"); List<NameValuePair> formParams = new ArrayList<NameValuePair>(); //表單參數(shù) formParams.add(new BasicNameValuePair("name1", "value1")); formParams.add(new BasicNameValuePair("name2", "value2")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, "utf-8"); httpPost.setEntity(entity); CloseableHttpResponse response = httpClient.execute(httpPost); System.out.println(EntityUtils.toString(response.getEntity()));
- 提交payload參數(shù)
CloseableHttpClient httpClient = HttpClients.custom() .build(); HttpPost httpPost = new HttpPost("https://www.explame.com"); StringEntity entity = new StringEntity("{\"id\": \"1\"}"); httpPost.setEntity(entity); CloseableHttpResponse response = httpClient.execute(httpPost); System.out.println(EntityUtils.toString(response.getEntity()));
- post上傳文件
CloseableHttpClient httpClient = HttpClients.custom() .build(); HttpPost httpPost = new HttpPost("https://www.example.com"); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); //要上傳的文件 multipartEntityBuilder.addBinaryBody("file", new File("temp.txt")); httpPost.setEntity(multipartEntityBuilder.build()); CloseableHttpResponse response = httpClient.execute(httpPost); System.out.println(EntityUtils.toString(response.getEntity()));
- post提交multipart/form-data類型參數(shù)
CloseableHttpClient httpClient = HttpClients.custom() .build(); HttpPost httpPost = new HttpPost("https://www.example.com"); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); multipartEntityBuilder.addTextBody("username","wycm"); multipartEntityBuilder.addTextBody("passowrd","123"); //文件 multipartEntityBuilder.addBinaryBody("file", new File("temp.txt")); httpPost.setEntity(multipartEntityBuilder.build()); CloseableHttpResponse response = httpClient.execute(httpPost); System.out.println(EntityUtils.toString(response.getEntity()));
- 提交form表單參數(shù)
-
設置User-Agent
CloseableHttpClient httpClient = HttpClients.custom() .setUserAgent("Mozilla/5.0") .build(); CloseableHttpResponse response = httpClient.execute(new HttpGet("https://www.baidu.com")); System.out.println(EntityUtils.toString(response.getEntity()));
-
設置重試處理器
當請求超時, 會自動重試,最多3次HttpRequestRetryHandler retryHandler = (exception, executionCount, context) -> { if (executionCount >= 3) { return false; } if (exception instanceof InterruptedIOException) { return true; } if (exception instanceof UnknownHostException) { return true; } if (exception instanceof ConnectTimeoutException) { return true; } if (exception instanceof SSLException) { return true; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) { return true; } return false; }; CloseableHttpClient httpClient = HttpClients.custom() .setRetryHandler(retryHandler) .build(); httpClient.execute(new HttpGet("https://www.baidu.com"));
-
重定向策略
- HttpClient默認情況
會對302、307的GET和HEAD請求以及所有的303狀態(tài)碼做重定向處理 - 關閉自動重定向
CloseableHttpClient httpClient = HttpClients.custom() //關閉httpclient重定向 .disableRedirectHandling() .build();
- POST支持302狀態(tài)碼重定向
CloseableHttpClient httpClient = HttpClients.custom() //post 302支持重定向 .setRedirectStrategy(new LaxRedirectStrategy()) .build(); CloseableHttpResponse response = httpClient.execute(new HttpPost("https://www.explame.com")); System.out.println(EntityUtils.toString(response.getEntity()));
- HttpClient默認情況
-
定制cookie
- 方式一:通過addHeader方式設置(不推薦這種方式)
由于HttpClient默認會維護cookie狀態(tài)。如果這個請求response中有Set-Cookie頭,那下次請求的時候httpclient默認會把這個Cookie帶上。并且會新建一行header。如果再遇到CloseableHttpClient httpClient = HttpClients.custom() .build(); HttpGet httpGet = new HttpGet("http://www.example.com"); httpGet.addHeader("Cookie", "name=value"); httpClient.execute(httpGet);
httpGet.addHeader("Cookie", "name=value");
那么下次請求則會有兩行name為Cookie的header。 - 方式二:通過CookieStore的方式,以瀏覽器中的cookie為例(推薦)
這種方式把定制的cookie交給httpclient維護。//此處直接粘貼瀏覽器cookie final String RAW_COOKIES = "name1=value1; name2=value2"; final CookieStore cookieStore = new BasicCookieStore(); for (String rawCookie : RAW_COOKIES.split("; ")){ String[] s = rawCookie.split("="); BasicClientCookie cookie = new BasicClientCookie(s[0], s[1]); cookie.setDomain("baidu.com"); cookie.setPath("/"); cookie.setSecure(false); cookie.setAttribute("domain", "baidu.com"); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, +5); cookie.setExpiryDate(calendar.getTime()); cookieStore.addCookie(cookie); } CloseableHttpClient httpClient = HttpClients.custom() .setDefaultCookieStore(cookieStore) .build(); httpClient.execute(new HttpGet("https://www.baidu.com"));
- 方式一:通過addHeader方式設置(不推薦這種方式)
-
cookie管理
- 方式一:初始化HttpClient時,傳入一個自己CookieStore對象
CookieStore cookieStore = new BasicCookieStore(); CloseableHttpClient httpClient = HttpClients.custom() .setDefaultCookieStore(cookieStore) .build(); httpClient.execute(new HttpGet("https://www.baidu.com")); //請求一次后,清理cookie再發(fā)起一次新的請求 cookieStore.clear(); httpClient.execute(new HttpGet("https://www.baidu.com"));
- 方式二:每次執(zhí)行請求的時候傳入自己的HttpContext對象
//注:HttpClientContext不是線程安全的,不要多個線程維護一個HttpClientContext HttpClientContext httpContext = HttpClientContext.create(); CloseableHttpClient httpClient = HttpClients.custom() .build(); httpClient.execute(new HttpGet("https://www.baidu.com"), httpContext); //請求一次后,清理cookie再發(fā)起一次新的請求 httpContext.getCookieStore().clear(); httpClient.execute(new HttpGet("https://www.baidu.com"));
- 方式一:初始化HttpClient時,傳入一個自己CookieStore對象
-
http代理的配置
CloseableHttpClient httpClient = HttpClients.custom() //設置代理 .setRoutePlanner(new DefaultProxyRoutePlanner(new HttpHost("localhost", 8888))) .build(); CloseableHttpResponse response = httpClient.execute(new HttpGet("http://www.example.com")); System.out.println(EntityUtils.toString(response.getEntity()));
-
SSL配置
//默認信任 SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()) , (chain, authType) -> true).build(); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new SocketProxyPlainConnectionSocketFactory()) .register("https", new SocketProxySSLConnectionSocketFactory(sslContext)) .build(); CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(new PoolingHttpClientConnectionManager(socketFactoryRegistry)) .build(); HttpClientContext httpClientContext = HttpClientContext.create(); httpClientContext.setAttribute("socks.address", new InetSocketAddress("127.0.0.1", 1086)); CloseableHttpResponse response = httpClient.execute(new HttpGet("https://httpbin.org/ip"), httpClientContext); System.out.println(EntityUtils.toString(response.getEntity()));
-
socket代理配置
static class SocketProxyPlainConnectionSocketFactory extends PlainConnectionSocketFactory{ @Override public Socket createSocket(final HttpContext context) { InetSocketAddress socksAddr = (InetSocketAddress) context.getAttribute("socks.address"); if (socksAddr != null){ Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr); return new Socket(proxy); } else { return new Socket(); } } } static class SocketProxySSLConnectionSocketFactory extends SSLConnectionSocketFactory { public SocketProxySSLConnectionSocketFactory(final SSLContext sslContext) { super(sslContext, NoopHostnameVerifier.INSTANCE); } @Override public Socket createSocket(final HttpContext context) { InetSocketAddress socksAddr = (InetSocketAddress) context.getAttribute("socks.address"); if (socksAddr != null){ Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr); return new Socket(proxy); } else { return new Socket(); } } } /** * socket代理配置 */ public static void socketProxy() throws Exception { //默認信任 SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()) , (X509Certificate[] chain, String authType) -> true).build(); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new SocketProxyPlainConnectionSocketFactory()) .register("https", new SocketProxySSLConnectionSocketFactory(sslContext)) .build(); CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(new PoolingHttpClientConnectionManager(socketFactoryRegistry)) .build(); HttpClientContext httpClientContext = HttpClientContext.create(); httpClientContext.setAttribute("socks.address", new InetSocketAddress("127.0.0.1", 1086)); CloseableHttpResponse response = httpClient.execute(new HttpGet("https://httpbin.org/ip"), httpClientContext); System.out.println(EntityUtils.toString(response.getEntity())); }
-
下載文件
CloseableHttpClient httpClient = HttpClients.custom().build(); CloseableHttpResponse response = httpClient.execute(new HttpGet("https://www.example.com")); InputStream is = response.getEntity().getContent(); Files.copy(is, new File("temp.png").toPath(), StandardCopyOption.REPLACE_EXISTING);
最后
- 完整Demo源碼下載地址:https://github.com/wycm/HttpClientDemo
版權聲明
作者:wycm
出處:http://www.lxweimin.com/p/e6980bb463e9
您的支持是對博主最大的鼓勵,感謝您的認真閱讀。
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。