1、HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也方便提高代码的健壮性。
2、org.apache.commons.httpclient.HttpClient与org.apache.http.client.HttpClient的区别?
org.apache.commons.httpclient.HttpClient的HttpClient项目已经不再被开发新版本, 已被Apache HttpComponents项目HttpClient和HttpCore 模组取代,提供更好的性能和更大的灵活性,所以在开发中使用后者来学习或者实践的哦!
3、HttpClient 提供的主要功能,如下所示:
1)、实现了所有 HTTP 的方法(Get、Post、Put、Head 等)。
2)、支持自动转向。
3)、支持 HTTPS 协议。
4)、支持代理服务器等。
4、httpClient的使用方法,使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可,如下所示:
1)、创建HttpClient对象。
2)、创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象。如果需要发送POST请求,创建HttpPost对象。
3)、如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数。对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
4)、调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
5)、调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容,此时可以对返回的结果进行处理和操作。程序可通过该对象获取服务器的响应内容。
6)、释放连接。无论执行方法是否成功,都必须释放连接。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 4 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.bie</groupId> 8 <artifactId>httpClient</artifactId> 9 <version>0.0.1-SNAPSHOT</version> 10 <packaging>jar</packaging> 11 12 <name>httpClient</name> 13 <url>http://maven.apache.org</url> 14 15 <properties> 16 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 17 </properties> 18 19 <dependencies> 20 <dependency> 21 <groupId>junit</groupId> 22 <artifactId>junit</artifactId> 23 <version>3.8.1</version> 24 <scope>test</scope> 25 </dependency> 26 <!-- httpclient的版本是4.5.2 --> 27 <dependency> 28 <groupId>org.apache.httpcomponents</groupId> 29 <artifactId>httpclient</artifactId> 30 <version>4.5.2</version> 31 </dependency> 32 <!-- apache流相关的依赖 --> 33 <dependency> 34 <groupId>commons-io</groupId> 35 <artifactId>commons-io</artifactId> 36 <version>2.5</version> 37 </dependency> 38 </dependencies> 39 40 </project>
案例,代码,如下所示:
1 package com.bie.httpClient; 2 3 import java.io.IOException; 4 5 import org.apache.http.HttpEntity; 6 import org.apache.http.ParseException; 7 import org.apache.http.client.ClientProtocolException; 8 import org.apache.http.client.methods.CloseableHttpResponse; 9 import org.apache.http.client.methods.HttpGet; 10 import org.apache.http.impl.client.CloseableHttpClient; 11 import org.apache.http.impl.client.HttpClients; 12 import org.apache.http.util.EntityUtils; 13 14 /** 15 * 16 * @author 17 * 18 */ 19 public class HttpClientHello { 20 21 /** 22 * HttpGet请求操作 23 */ 24 public static void httpGetRequest() { 25 // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。 26 CloseableHttpClient httpClient = HttpClients.createDefault(); 27 // 第二步,创建HttpGet或者HttpPost实例。 28 String uri = "https://www.cnblogs.com/"; 29 HttpGet httpGet = new HttpGet(uri); 30 // 定义一个可响应的实例对象。 31 CloseableHttpResponse response = null; 32 try { 33 // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。 34 response = httpClient.execute(httpGet); 35 } catch (ClientProtocolException e) { 36 // http协议异常 37 e.printStackTrace(); 38 } catch (IOException e) { 39 // io异常 40 e.printStackTrace(); 41 } 42 // 第四步,获取到返回的实体对象 43 HttpEntity entity = response.getEntity(); 44 // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码 45 String result = null; 46 try { 47 result = EntityUtils.toString(entity, "UTF-8"); 48 } catch (ParseException e) { 49 e.printStackTrace(); 50 } catch (IOException e) { 51 e.printStackTrace(); 52 } 53 // 打印请求返回的结果 54 System.out.println(result.toString()); 55 56 // 第五步,关闭流,释放资源 57 try { 58 response.close(); 59 httpClient.close(); 60 } catch (IOException e) { 61 e.printStackTrace(); 62 } 63 } 64 65 public static void main(String[] args) { 66 HttpClientHello.httpGetRequest(); 67 } 68 69 }
带参数的GET请求,如下所示:
1 package com.bie.spider.httpClient; 2 3 import java.io.IOException; 4 import java.net.URI; 5 import java.net.URISyntaxException; 6 7 import org.apache.http.HttpEntity; 8 import org.apache.http.client.ClientProtocolException; 9 import org.apache.http.client.methods.CloseableHttpResponse; 10 import org.apache.http.client.methods.HttpGet; 11 import org.apache.http.client.utils.URIBuilder; 12 import org.apache.http.impl.client.CloseableHttpClient; 13 import org.apache.http.impl.client.HttpClients; 14 import org.apache.http.util.EntityUtils; 15 16 public class HttpClient { 17 18 // 设置请求头消息 User-Agent 模拟浏览器 19 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 20 21 public static void main(String[] args) throws ClientProtocolException, IOException, URISyntaxException { 22 // 第一步,打开浏览器,创建HttpClient对象 23 CloseableHttpClient httpClient = HttpClients.createDefault(); 24 25 // 声明访问地址 26 URI uri = new URIBuilder("https://www.baidu.com/s").setParameter("wd", "汽车之家").build(); 27 28 // 第二步,输入网址,发起get请求创建httpGet请求 29 HttpGet httpGet = new HttpGet(uri); 30 // 设置请求头消息 User-Agent 模拟浏览器 31 httpGet.setHeader("User-Agent", UserAgent); 32 33 // 第三步,发起请求,返回响应,使用httpClient对象发起请求 34 CloseableHttpResponse response = httpClient.execute(httpGet); 35 36 // 第四步,解析响应,获取数据,首先判断状态是否是200正常状态 37 if (response.getStatusLine().getStatusCode() == 200) { 38 // 解析数据 39 HttpEntity entity = response.getEntity(); 40 String str = EntityUtils.toString(entity, "utf8"); 41 System.out.println(str.toString()); 42 } 43 44 // 第五步,关闭流,释放连接 45 response.close(); 46 httpClient.close(); 47 48 } 49 50 }
5、设置请求头消息 User-Agent 模拟各种不同的浏览器,可以获取到不让你随便获取到页面。获取响应内容类型 Content-Type,可以根据此响应类型来过滤出自己想要的或者不想要的内容信息。获取响应状态 Status,根据响应的状态码来判断请求是否成功。
1 package com.bie.httpClient.httpGet; 2 3 import java.io.IOException; 4 5 import org.apache.http.Header; 6 import org.apache.http.HttpEntity; 7 import org.apache.http.ParseException; 8 import org.apache.http.StatusLine; 9 import org.apache.http.client.ClientProtocolException; 10 import org.apache.http.client.methods.CloseableHttpResponse; 11 import org.apache.http.client.methods.HttpGet; 12 import org.apache.http.impl.client.CloseableHttpClient; 13 import org.apache.http.impl.client.HttpClients; 14 import org.apache.http.util.EntityUtils; 15 16 /** 17 * 18 * @author 19 * 20 */ 21 public class HttpClientHttpGet { 22 23 // 设置请求头消息 User-Agent 模拟浏览器 24 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 25 26 /** 27 * HttpGet请求操作 28 */ 29 public static void httpGetRequest() { 30 // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。 31 CloseableHttpClient httpClient = HttpClients.createDefault(); 32 // 第二步,创建HttpGet或者HttpPost实例。 33 String uri = "https://www.tuicool.com/"; 34 HttpGet httpGet = new HttpGet(uri); 35 // 设置请求头消息 User-Agent 模拟浏览器 36 httpGet.setHeader("User-Agent", UserAgent); 37 38 // 定义一个可响应的实例对象。 39 CloseableHttpResponse response = null; 40 try { 41 // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。 42 response = httpClient.execute(httpGet); 43 // 获取到响应的状态 44 StatusLine statusLine = response.getStatusLine(); 45 System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode()); 46 } catch (ClientProtocolException e) { 47 // http协议异常 48 e.printStackTrace(); 49 } catch (IOException e) { 50 // io异常 51 e.printStackTrace(); 52 } 53 // 第四步,获取到返回的实体对象 54 HttpEntity entity = response.getEntity(); 55 // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西 56 Header contentType = entity.getContentType(); 57 // 打印响应信息 58 System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue()); 59 60 // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码 61 String result = null; 62 try { 63 result = EntityUtils.toString(entity, "UTF-8"); 64 } catch (ParseException e) { 65 e.printStackTrace(); 66 } catch (IOException e) { 67 e.printStackTrace(); 68 } 69 // 打印请求返回的结果 70 // System.out.println(result.toString()); 71 72 // 第五步,关闭流,释放资源 73 try { 74 response.close(); 75 httpClient.close(); 76 } catch (IOException e) { 77 e.printStackTrace(); 78 } 79 } 80 81 public static void main(String[] args) { 82 HttpClientHttpGet.httpGetRequest(); 83 } 84 85 }
6、如何获取网上的一张图片,然后保存到本地的操作,代码如下所示:
1 package com.bie.httpClient.getImage; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 7 import org.apache.commons.io.FileUtils; 8 import org.apache.http.Header; 9 import org.apache.http.HttpEntity; 10 import org.apache.http.ParseException; 11 import org.apache.http.StatusLine; 12 import org.apache.http.client.ClientProtocolException; 13 import org.apache.http.client.methods.CloseableHttpResponse; 14 import org.apache.http.client.methods.HttpGet; 15 import org.apache.http.impl.client.CloseableHttpClient; 16 import org.apache.http.impl.client.HttpClients; 17 18 /** 19 * 20 * @author 21 * 22 */ 23 public class HttpClientGetImage { 24 25 // 设置请求头消息 User-Agent 模拟浏览器 26 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 27 28 /** 29 * HttpGet请求操作 30 */ 31 public static void httpGetRequest() { 32 // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。 33 CloseableHttpClient httpClient = HttpClients.createDefault(); 34 // 第二步,创建HttpGet或者HttpPost实例。 35 String uri = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=179511720,320422354&fm=26&gp=0.jpg"; 36 HttpGet httpGet = new HttpGet(uri); 37 // 设置请求头消息 User-Agent 模拟浏览器 38 httpGet.setHeader("User-Agent", UserAgent); 39 40 // 定义一个可响应的实例对象。 41 CloseableHttpResponse response = null; 42 try { 43 // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。 44 response = httpClient.execute(httpGet); 45 // 获取到响应的状态 46 StatusLine statusLine = response.getStatusLine(); 47 System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode()); 48 } catch (ClientProtocolException e) { 49 // http协议异常 50 e.printStackTrace(); 51 } catch (IOException e) { 52 // io异常 53 e.printStackTrace(); 54 } 55 // 第四步,获取到返回的实体对象 56 HttpEntity entity = response.getEntity(); 57 // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西 58 Header contentType = entity.getContentType(); 59 // 打印响应信息 60 System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue()); 61 62 // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码 63 String result = null; 64 try { 65 // 判断entity是否为空 66 if (entity != null) { 67 InputStream content = entity.getContent(); 68 // 将下载的内容拷贝到指定的文件夹下面 69 File file = new File("F:\" + "hashiqi.jpg"); 70 FileUtils.copyToFile(content, file); 71 System.out.println("--------------------------------执行成功--------------------------------"); 72 } 73 } catch (ParseException e) { 74 e.printStackTrace(); 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 // 第五步,关闭流,释放资源 79 try { 80 response.close(); 81 httpClient.close(); 82 } catch (IOException e) { 83 e.printStackTrace(); 84 } 85 } 86 87 public static void main(String[] args) { 88 HttpClientGetImage.httpGetRequest(); 89 } 90 91 }
7、httpClient使用代理ip,在爬取网页的时候,有的目标站点有反爬虫机制,对于频繁访问站点以及规则性访问站点的行为,会采取屏蔽ip的措施,这时候使用代理Ip就有大用处了。代理ip分为透明代理,匿名代理,混淆代理,高匿代理。
1)、透明代理(Transparent Proxy),透明代理虽然可以直接“隐藏”你的IP地址,但是还是可以从HTTP_X_FORWARDED_FOR来查到你是谁。
2)、匿名代理(Anonymous Proxy),匿名代理比透明代理进步了一点:别人只能知道你用了代理,无法知道你是谁。
3)、混淆代理(Distorting Proxies),与匿名代理相同,如果使用了混淆代理,别人还是能知道你在用代理,但是会得到一个假的IP地址,找不到你。
4)、高匿代理(Elite proxy或High Anonymity Proxy),可以看出来,高匿代理让别人根本无法发现你是在用代理,所以是最好的选择。
代理IP :http://www.66ip.cn/index.html,更多的可以百度。
1 package com.bie.httpClient.ip; 2 3 import java.io.IOException; 4 5 import org.apache.http.Header; 6 import org.apache.http.HttpEntity; 7 import org.apache.http.HttpHost; 8 import org.apache.http.ParseException; 9 import org.apache.http.StatusLine; 10 import org.apache.http.client.ClientProtocolException; 11 import org.apache.http.client.config.RequestConfig; 12 import org.apache.http.client.methods.CloseableHttpResponse; 13 import org.apache.http.client.methods.HttpGet; 14 import org.apache.http.impl.client.CloseableHttpClient; 15 import org.apache.http.impl.client.HttpClients; 16 import org.apache.http.util.EntityUtils; 17 18 /** 19 * 20 * @author 21 * 22 */ 23 public class HttpClientProxyIp { 24 25 // 设置请求头消息 User-Agent 模拟浏览器 26 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 27 28 /** 29 * HttpGet请求操作 30 */ 31 public static void httpGetRequest() { 32 // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。 33 CloseableHttpClient httpClient = HttpClients.createDefault(); 34 // 第二步,创建HttpGet或者HttpPost实例。 35 String uri = "http://www.baidu.com/"; 36 HttpGet httpGet = new HttpGet(uri); 37 // 设置请求头消息 User-Agent 模拟浏览器 38 httpGet.setHeader("User-Agent", UserAgent); 39 40 // 设置ip代理,这里设置高匿代理 41 HttpHost proxy = new HttpHost("183.195.106.118", 8118); 42 RequestConfig config = RequestConfig.custom().setProxy(proxy).build(); 43 httpGet.setConfig(config); 44 45 // 定义一个可响应的实例对象。 46 CloseableHttpResponse response = null; 47 try { 48 // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。 49 response = httpClient.execute(httpGet); 50 // 获取到响应的状态 51 StatusLine statusLine = response.getStatusLine(); 52 System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode()); 53 } catch (ClientProtocolException e) { 54 // http协议异常 55 e.printStackTrace(); 56 } catch (IOException e) { 57 // io异常 58 e.printStackTrace(); 59 } 60 // 第四步,获取到返回的实体对象 61 HttpEntity entity = response.getEntity(); 62 // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西 63 Header contentType = entity.getContentType(); 64 // 打印响应信息 65 System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue()); 66 67 // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码 68 String result = null; 69 try { 70 result = EntityUtils.toString(entity, "UTF-8"); 71 } catch (ParseException e) { 72 e.printStackTrace(); 73 } catch (IOException e) { 74 e.printStackTrace(); 75 } 76 // 打印请求返回的结果 77 System.out.println(result.toString()); 78 79 // 第五步,关闭流,释放资源 80 try { 81 response.close(); 82 httpClient.close(); 83 } catch (IOException e) { 84 e.printStackTrace(); 85 } 86 } 87 88 public static void main(String[] args) { 89 System.out.println(System.currentTimeMillis()); 90 HttpClientProxyIp.httpGetRequest(); 91 System.out.println(System.currentTimeMillis()); 92 } 93 94 }
8、HttpClient连接超时及读取超时问题,httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间。
1)、HttpClient连接时间,所谓连接的时间,是指HttpClient发送请求的地方开始到连接上目标url主机地址的时间,理论上是距离越短越快。
2)、HttpClient读取时间,所谓读取的时间,是指HttpClient已经连接到了目标服务器,然后进行内容数据的获取,一般情况 读取数据都是很快速的,但是假如读取的数据量大,或者是目标服务器本身的问题(比如读取数据库速度慢,并发量大等等)也会影响读取时间。
1 package com.bie.httpClient.timeout; 2 3 import java.io.IOException; 4 5 import org.apache.http.Header; 6 import org.apache.http.HttpEntity; 7 import org.apache.http.ParseException; 8 import org.apache.http.StatusLine; 9 import org.apache.http.client.ClientProtocolException; 10 import org.apache.http.client.config.RequestConfig; 11 import org.apache.http.client.methods.CloseableHttpResponse; 12 import org.apache.http.client.methods.HttpGet; 13 import org.apache.http.impl.client.CloseableHttpClient; 14 import org.apache.http.impl.client.HttpClients; 15 import org.apache.http.util.EntityUtils; 16 17 /** 18 * 19 * @author 20 * 21 */ 22 public class HttpClientTimeOut { 23 24 // 设置请求头消息 User-Agent 模拟浏览器 25 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 26 27 /** 28 * HttpGet请求操作 29 */ 30 public static void httpGetRequest() { 31 // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。 32 CloseableHttpClient httpClient = HttpClients.createDefault(); 33 // 第二步,创建HttpGet或者HttpPost实例。 34 String uri = "https://www.baidu.com/"; 35 HttpGet httpGet = new HttpGet(uri); 36 // 设置请求头消息 User-Agent 模拟浏览器 37 httpGet.setHeader("User-Agent", UserAgent); 38 39 // HttpClient提供了一个RequestConfig类,专门用于配置参数比如连接时间、读取时间、代理IP等。 40 RequestConfig config = RequestConfig 41 .custom() 42 .setConnectTimeout(5000) // 设置连接时间5秒钟 43 .setSocketTimeout(5000) // 设置响应时间5秒钟 44 .build(); 45 httpGet.setConfig(config); 46 47 // 定义一个可响应的实例对象。 48 CloseableHttpResponse response = null; 49 try { 50 // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。 51 response = httpClient.execute(httpGet); 52 // 获取到响应的状态 53 StatusLine statusLine = response.getStatusLine(); 54 System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode()); 55 } catch (ClientProtocolException e) { 56 // http协议异常 57 e.printStackTrace(); 58 } catch (IOException e) { 59 // io异常 60 e.printStackTrace(); 61 } 62 // 第四步,获取到返回的实体对象 63 HttpEntity entity = response.getEntity(); 64 65 // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西 66 Header contentType = entity.getContentType(); 67 // 打印响应信息 68 System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue()); 69 70 // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码 71 String result = null; 72 try { 73 result = EntityUtils.toString(entity, "UTF-8"); 74 } catch (ParseException e) { 75 e.printStackTrace(); 76 } catch (IOException e) { 77 e.printStackTrace(); 78 } 79 // 打印请求返回的结果 80 System.out.println(result.toString()); 81 82 // 第五步,关闭流,释放资源 83 try { 84 response.close(); 85 httpClient.close(); 86 } catch (IOException e) { 87 e.printStackTrace(); 88 } 89 } 90 91 public static void main(String[] args) { 92 HttpClientTimeOut.httpGetRequest(); 93 } 94 95 }
9、可以使用httpPost请求来模拟表单请求操作,非常适合于接口测试,当然也有很多工具来进行接口测试,比如Postman等等,如下所示:
1 package com.bie.httpClient.httpPost; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import org.apache.http.HttpEntity; 8 import org.apache.http.NameValuePair; 9 import org.apache.http.ParseException; 10 import org.apache.http.client.ClientProtocolException; 11 import org.apache.http.client.entity.UrlEncodedFormEntity; 12 import org.apache.http.client.methods.CloseableHttpResponse; 13 import org.apache.http.client.methods.HttpPost; 14 import org.apache.http.impl.client.CloseableHttpClient; 15 import org.apache.http.impl.client.HttpClients; 16 import org.apache.http.message.BasicNameValuePair; 17 import org.apache.http.util.EntityUtils; 18 19 /** 20 * 21 * @author 22 * 23 */ 24 public class HttpClientHttpPost { 25 26 /** 27 * HttpGet请求操作 28 */ 29 public static void httpGetRequest() { 30 // 获取到开始时间 31 long startTime = System.currentTimeMillis(); 32 // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。 33 CloseableHttpClient httpClient = HttpClients.createDefault(); 34 // 第二步,创建HttpGet或者HttpPost实例。 35 String uri = "http://127.0.0.1:8080/login"; 36 HttpPost httpPost = new HttpPost(uri); 37 // 定义一个可响应的实例对象。 38 CloseableHttpResponse response = null; 39 try { 40 // 定义一个List集合用于保存表单请求数据 41 List<NameValuePair> list = new ArrayList<NameValuePair>(); 42 list.add(new BasicNameValuePair("userName", "admin")); 43 list.add(new BasicNameValuePair("password", "123456")); 44 45 // 定义一个表单实体对象,设置字符集编码为utf-8 46 UrlEncodedFormEntity uefEntity = uefEntity = new UrlEncodedFormEntity(list, "UTF-8"); 47 // 将实体对象设置到httpPost请求对象中 48 httpPost.setEntity(uefEntity); 49 System.out.println("executing request " + httpPost.getURI()); 50 51 // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。 52 response = httpClient.execute(httpPost); 53 } catch (ClientProtocolException e) { 54 // http协议异常 55 e.printStackTrace(); 56 } catch (IOException e) { 57 // io异常 58 e.printStackTrace(); 59 } 60 // 第四步,获取到返回的实体对象 61 HttpEntity entity = response.getEntity(); 62 // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码 63 String result = null; 64 try { 65 if (entity != null) { 66 result = EntityUtils.toString(entity, "UTF-8"); 67 } 68 } catch (ParseException e) { 69 e.printStackTrace(); 70 } catch (IOException e) { 71 e.printStackTrace(); 72 } 73 // 打印请求返回的结果 74 System.out.println(result.toString()); 75 76 long endTime = System.currentTimeMillis(); 77 System.out.println("程序运行时间: " + (endTime - startTime) + "ms"); 78 79 // 第五步,关闭流,释放资源 80 try { 81 response.close(); 82 httpClient.close(); 83 } catch (IOException e) { 84 e.printStackTrace(); 85 } 86 } 87 88 public static void main(String[] args) { 89 HttpClientHttpPost.httpGetRequest(); 90 } 91 92 }
如果每次请求都要创建httpClient,会有频繁的创建和销毁的问题,可以使用连接池来解决这个问题,如下所示:
1 package com.bie.spider.httpClient; 2 3 import java.io.IOException; 4 import java.net.URISyntaxException; 5 6 import org.apache.http.HttpEntity; 7 import org.apache.http.client.ClientProtocolException; 8 import org.apache.http.client.methods.CloseableHttpResponse; 9 import org.apache.http.client.methods.HttpGet; 10 import org.apache.http.impl.client.CloseableHttpClient; 11 import org.apache.http.impl.client.HttpClients; 12 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 13 import org.apache.http.util.EntityUtils; 14 15 public class HttpClient { 16 17 // 设置请求头消息 User-Agent 模拟浏览器 18 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 19 20 /** 21 * 发送http get请求 22 * 23 * @throws ClientProtocolException 24 * @throws IOException 25 */ 26 public static void httpClientGet() throws ClientProtocolException, IOException { 27 // 从连接池中获取连接 28 PoolingHttpClientConnectionManager httpClientPool = httpClientPool(); 29 // 第一步,打开浏览器,创建HttpClient对象 30 // 从连接池中获取到连接 31 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(httpClientPool).build(); 32 33 // 声明访问地址 34 // URI uri = new URIBuilder("https://www.baidu.com/s").setParameter("wd", 35 // "汽车之家").build(); 36 37 // 第二步,输入网址,发起get请求创建httpGet请求,声明访问地址 38 HttpGet httpGet = new HttpGet("http://www.baidu.com/"); 39 // 设置请求头消息 User-Agent 模拟浏览器 40 httpGet.setHeader("User-Agent", UserAgent); 41 42 // 第三步,发起请求,返回响应,使用httpClient对象发起请求 43 CloseableHttpResponse response = httpClient.execute(httpGet); 44 45 // 第四步,解析响应,获取数据,首先判断状态是否是200正常状态 46 if (response.getStatusLine().getStatusCode() == 200) { 47 // 解析数据 48 HttpEntity entity = response.getEntity(); 49 String str = EntityUtils.toString(entity, "utf8"); 50 System.out.println(str.toString()); 51 } 52 53 // 第五步,关闭流,释放连接 54 if (response != null) { 55 response.close(); 56 } 57 // 不能关闭HttpClient 58 // httpClient.close(); 59 } 60 61 /** 62 * 连接池配置 63 * 64 * @return 65 */ 66 public static PoolingHttpClientConnectionManager httpClientPool() { 67 // 创建连接池管理器 68 PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(); 69 // 设置最大连接数 70 clientConnectionManager.setMaxTotal(200); 71 // 设置每隔主机的并发数 72 clientConnectionManager.setDefaultMaxPerRoute(20); 73 return clientConnectionManager; 74 } 75 76 public static void main(String[] args) throws ClientProtocolException, IOException, URISyntaxException { 77 httpClientGet(); 78 } 79 80 }
有时候因为网络或者目标服务器的原因,请求需要更长的时间才能完成,我们需要自定义相关的请求时间和响应时间,如下所示:
1 package com.bie.spider.httpClient; 2 3 import java.io.IOException; 4 import java.net.URISyntaxException; 5 6 import org.apache.http.HttpEntity; 7 import org.apache.http.client.ClientProtocolException; 8 import org.apache.http.client.config.RequestConfig; 9 import org.apache.http.client.methods.CloseableHttpResponse; 10 import org.apache.http.client.methods.HttpGet; 11 import org.apache.http.impl.client.CloseableHttpClient; 12 import org.apache.http.impl.client.HttpClients; 13 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 14 import org.apache.http.util.EntityUtils; 15 16 public class HttpClient { 17 18 // 设置请求头消息 User-Agent 模拟浏览器 19 private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"; 20 21 /** 22 * 发送http get请求 23 * 24 * @throws ClientProtocolException 25 * @throws IOException,单位是毫秒 26 */ 27 public static void httpClientGet() throws ClientProtocolException, IOException { 28 // 从连接池中获取连接 29 PoolingHttpClientConnectionManager httpClientPool = httpClientPool(); 30 // 第一步,打开浏览器,创建HttpClient对象 31 // 从连接池中获取到连接 32 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(httpClientPool).build(); 33 34 // 声明访问地址 35 // URI uri = new URIBuilder("https://www.baidu.com/s").setParameter("wd", 36 // "汽车之家").build(); 37 38 // 构建请求配置信息 39 RequestConfig config = RequestConfig.custom() 40 .setConnectTimeout(1000) // 创建连接的最长时间,单位是毫秒 41 .setConnectionRequestTimeout(500) // 从连接池中获取到连接的最长时间,单位是毫秒 42 .setSocketTimeout(10 * 1000) // 数据传输的最长时间,单位是毫秒 43 .build(); 44 45 // 第二步,输入网址,发起get请求创建httpGet请求,声明访问地址 46 HttpGet httpGet = new HttpGet("http://www.baidu.com/"); 47 // 设置请求头消息 User-Agent 模拟浏览器 48 httpGet.setHeader("User-Agent", UserAgent); 49 // 设置请求配置信息 50 httpGet.setConfig(config); 51 52 // 第三步,发起请求,返回响应,使用httpClient对象发起请求 53 CloseableHttpResponse response = httpClient.execute(httpGet); 54 55 // 第四步,解析响应,获取数据,首先判断状态是否是200正常状态 56 if (response.getStatusLine().getStatusCode() == 200) { 57 // 解析数据 58 HttpEntity entity = response.getEntity(); 59 String str = EntityUtils.toString(entity, "utf8"); 60 System.out.println(str.toString()); 61 } 62 63 // 第五步,关闭流,释放连接 64 if (response != null) { 65 response.close(); 66 } 67 // 不能关闭HttpClient 68 // httpClient.close(); 69 } 70 71 /** 72 * 连接池配置 73 * 74 * @return 75 */ 76 public static PoolingHttpClientConnectionManager httpClientPool() { 77 // 创建连接池管理器 78 PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(); 79 // 设置最大连接数 80 clientConnectionManager.setMaxTotal(200); 81 // 设置每隔主机的并发数 82 clientConnectionManager.setDefaultMaxPerRoute(20); 83 return clientConnectionManager; 84 } 85 86 public static void main(String[] args) throws ClientProtocolException, IOException, URISyntaxException { 87 httpClientGet(); 88 } 89 90 }