HttpClient入门学习一

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 }

 

posted on 2020-11-29 20:06  别先生  阅读(369)  评论(0编辑  收藏  举报